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

时间:2017-04-27 20:09:29

标签: c++ linux multithreading process openmp

我的OpenMP程序中有一些非常不寻常的行为,我认为这些行为必定是由我不知道的Linux进程的一些内部工作引起的。

当我运行已经使用OpenMP支持编译的C基准二进制文件时,程序执行成功,完全没有问题:

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

当我从我开始的单独的C ++程序运行基准测试时,执行它的代码(例如)看起来像:

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

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

    return 0;
}

输出给了我警告:

>:$ 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.

当我尝试将CPU亲和力设置为不存在的CPU并直接运行OpenMP基准测试时,这些警告是相同的警告

因此我假设唯一知道存在的CPU my_cpp_program是处理器ID 0.我在使用root时也会遇到同样的错误,所以我不认为这是权限问题?我还检查过system()执行的代码是否具有正确的环境变量以及相同的链接库。

有谁知道造成这种情况的原因是什么?

1 个答案:

答案 0 :(得分:0)

根据祖兰的建议,我很确定发生这种情况的原因是因为void get(std::initializer_list<std::tuple<int,bool>> props = {{1,true},{1,true}}) {} 的性质和汇编。使用bin/my_cpp_program进行编译非常重要 。事实证明,-fopenmp是针对GNU OpenMP实现库bin/my_cpp_program编译的,而libgomp程序是针对LLVM OpenMP实现库bin/benchmark编译的。

我不确定,但我认为发生的事情如下。 libomp是用于在GOMP_CPU_AFFINITIY中设置CPU关联的GNU环境变量。因此,因为设置了libgomp,所以在GOMP_CPU_AFFINITY中运行的单线程被绑定到CPU 0.我猜这个线程产生的任何子进程也必须在进一步使用时也只能将CPU 0视为其潜在的CPU bin/my_cpp_program亲和力分配。当产生的进程(来自环境)试图找到CPU 1-3时,这就给了我警告。

为了解决这个问题,我使用了GOMP_CPU_AFFINITY,它是Intel的CPU亲和力环境变量。 KMP_AFFINITY使用的libomp OpenMP运行时在设置bin/benchmark时优先于KMP_AFFINITY,并且无论出于何种原因,它都允许生成的子进程分配给GOMP_CPU_AFFINITY其他CPU。为此,我使用了:

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

这意味着程序在两个情况下按预期工作(每个逻辑核心以0到3的升序绑定),因为bin/my_cpp_program的CPU分配不再与bin/benchmark的分配,当一个产生另一个时。通过将verbose添加到以逗号分隔的列表中,可以检查这种情况。