在 Linux 中从单独的单线程进程生成多线程进程时出现问题

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

本文关键字:进程 多线程 问题 单独 单线程 Linux      更新时间:2023-10-16

我的 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 基准测试时收到的警告相同

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

有谁知道是什么原因导致这种情况发生?

根据祖兰的建议,我很确定发生这种情况的原因是因为bin/my_cpp_program的性质和编译。重要的是,它也-fopenmp一起编译。事实证明,bin/my_cpp_program是针对GNU OpenMP实现库libgomp编译的,而bin/benchmark程序是针对LLVM OpenMP实现库libomp编译的。

我不确定,但我认为发生的事情如下。GOMP_CPU_AFFINITIY是用于在libgomp中设置 CPU 亲和力的 GNU 环境变量。因此,由于设置了GOMP_CPU_AFFINITY,因此在bin/my_cpp_program中运行的单线程绑定到 CPU 0。我想该线程生成的任何子进程在使用进一步的GOMP_CPU_AFFINITY亲和力分配时也必须只将 CPU 0 视为其潜在 CPU。然后,当生成的进程(从环境中)尝试查找 CPU 1-3 时,这给了我警告。

为了解决这个问题,我使用了英特尔的 CPU 关联环境变量KMP_AFFINITYbin/benchmark使用的libompOpenMP 运行时在设置KMP_AFFINITYGOMP_CPU_AFFINITY时具有更高的优先级,无论出于何种原因,这都允许生成的子进程分配给其他 CPU。因此,为此,我使用了:

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

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