简体   繁体   English

在Linux中从单独的单线程进程产生多线程进程的问题

[英]Problems spawning a multi-threaded process from a separate single-threaded process in Linux

I've had some rather unusual behavior from my OpenMP program, which I think must be caused by some inner-workings of Linux processes that I am unaware of. 我的OpenMP程序有一些非常不寻常的行为,我认为这一定是由于我不知道的Linux进程的某些内部工作引起的。

When I run a C benchmark binary which has been compiled with OpenMP support, the program executes successfully, no problems at all: 当我运行已通过OpenMP支持编译的C基准二进制文件时,程序成功执行,一点问题都没有:

>:$ OMP_NUM_THREADS=4 GOMP_CPU_AFFINITY="0-3" /home/me/bin/benchmark
>:$ ...benchmark complete...

When I run the benchmark from a separate C++ program that I start, where the code to execute it (for example) looks like: 当我从一个单独的C ++程序运行基准测试时,执行该基准测试的代码(例如)如下所示:

int main(int argc, char* argv[]){

    system("/home/me/bin/benchmark");

    return 0;
}

The output gives me warnings: 输出给我警告:

>:$ home/me/bin/my_cpp_program
OMP: Warning #123: Ignoring invalid OS proc ID 1.
OMP: Warning #123: Ignoring invalid OS proc ID 2.
OMP: Warning #123: Ignoring invalid OS proc ID 3.

These warnings are the same warnings I get when I try to set CPU affinity to CPUs that don't exist, and run the OpenMP benchmark directly. 这些警告我尝试将CPU亲和力设置为不存在的CPU并直接运行OpenMP基准测试时收到的警告相同

I therefore assume that the only CPU my_cpp_program knows to exist is processor ID 0. I also get the same error when using root so I don't think it is a permissions problem? 因此,我假定唯一知道存在的CPU my_cpp_program是处理器my_cpp_program 。使用root时也会出现相同的错误,因此我不认为这是权限问题? I've also checked that the code executed by system() has the correct environment variables, and the same linked libraries. 我还检查了system()执行的代码是否具有正确的环境变量以及相同的链接库。

Does anyone know what is causing this to occur? 有谁知道是什么原因导致这种情况发生的?

Following a suggestion by Zulan, I'm pretty sure the reason this occurred was because of the nature and compilation of bin/my_cpp_program . 按照bin/my_cpp_program的建议,我很确定发生这种情况的原因是由于bin/my_cpp_program的性质和编译。 It was importantly also compiled with -fopenmp . 重要的是, 使用-fopenmp编译。 It turns out that bin/my_cpp_program was compiled against the GNU OpenMP implementation library libgomp , whereas the bin/benchmark program was compiled against the LLVM OpenMP implementation library libomp . 事实证明bin/my_cpp_program是针对GNU OpenMP实现库libgomp ,而bin/benchmark程序是针对LLVM OpenMP实现库libomp

I am not certain, but what I think happened was the following. 我不确定,但是我认为发生了以下事情。 GOMP_CPU_AFFINITIY is the GNU environment variable for setting CPU affinity in libgomp . GOMP_CPU_AFFINITIY是用于在libgomp设置CPU亲和力的GNU环境变量。 Therefore because GOMP_CPU_AFFINITY was set, the single-thread running in bin/my_cpp_program was bound to CPU 0. I guess any child processes spawned by that thread must also only see CPU 0 as its potential-CPUs when using further GOMP_CPU_AFFINITY affinity assignments. 因此,由于设置了GOMP_CPU_AFFINITY ,在bin/my_cpp_program运行的bin/my_cpp_program绑定到了bin/my_cpp_program我猜想,使用进一步的GOMP_CPU_AFFINITY相似性分配时,该线程产生的任何子进程也必须仅将CPU 0视为其潜在CPU。 This then gave me the warnings when the spawned process (from the environment) tries to find CPUs 1-3. 当(从环境中)生成的进程尝试查找CPU 1-3时,这给了我警告。

To workaround this I used KMP_AFFINITY which is Intel's CPU affinity environment variable. 要解决此问题,我使用了KMP_AFFINITY ,它是Intel的CPU关联性环境变量。 The libomp OpenMP runtime used by bin/benchmark gives a higher precedence to KMP_AFFINITY when both it and GOMP_CPU_AFFINITY are set, and for whatever reason this allows the spawned child process to assign to other CPUs. bin/benchmarkGOMP_CPU_AFFINITY同时设置时, bin/benchmark使用的libomp OpenMP运行时将赋予KMP_AFFINITY更高的优先级,并且无论出于何种原因,这都允许将生成的子进程分配给其他CPU。 So to do this, I used: 为此,我使用了:

KMP_AFFINITY=logical,granularity=fine ./bin/benchmark

This means the program works as expected (each logical core is bound in ascending order from 0 to 3) in both situations, as the CPU assignments of the bin/my_cpp_program no longer screw with the assignments of bin/benchmark , when one spawns the other. 这意味着程序在两种情况下bin/my_cpp_program预期工作(每个逻辑核心从0到3升序绑定),因为当一个生成另一个时, bin/my_cpp_program的CPU分配不再与bin/benchmark的分配bin/my_cpp_program This can be checked as truly occurring by adding verbose to the comma-separated list. 通过将verbose的逗号添加到逗号分隔的列表中,可以检查这是否确实发生。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM