我的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()
执行的代码是否具有正确的环境变量以及相同的链接库。
有谁知道造成这种情况的原因是什么?
答案 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
添加到以逗号分隔的列表中,可以检查这种情况。