为啥 OpenMP 程序只在一个线程中运行

Posted

技术标签:

【中文标题】为啥 OpenMP 程序只在一个线程中运行【英文标题】:Why OpenMP program runs only in one thread为什么 OpenMP 程序只在一个线程中运行 【发布时间】:2012-04-18 06:22:25 【问题描述】:

我刚刚用一个简单的 c 程序尝试了 OpenMP

test() 
   for(int i=0;i<100000000;i++);

main() 
    printf("Num of CPU: %d\n", omp_get_num_procs());
    #pragma omp parallel for num_threads(4)
    for(int i=0;i<100;i++) test();

使用g++ -fopenmp 编译。它可以正确打印出我有 4 个 CPU,但所有测试功能都在 thread 0 运行。

我尝试修改OMP_NUM_THREADS。但它也没有效果。

我的一切都与在线示例相同,但为什么我不能让它工作?

【问题讨论】:

你怎么知道它只运行一个线程? 是的,我通过打印出 omp_get_thread_num() 签入了 test()。 您是否检查过omp_get_max_threads() 以查看openmp 是否由于某种原因它只能使用一个线程? 谢谢,我在 test() 中检查了 omp_get_max_threads(),它是 4。但是每个 test() 仍然在线程号 0 上运行。 编译器是否有可能优化所有循环,因为它们什么都不做,然后每个线程完成的速度比创建它们的循环更快,因为它们什么都不做。 . 所以只有一个线程在运行。只是一个理论,可能是错误的:) 【参考方案1】:

你的问题在这里:

#pragma omp parallel for num_thread(4) <---

正确的子句是num_threads(4),而不是num_thread(4)。不正确的 openmp 编译指示将被忽略,因此您最终得到了一个顺序程序。 :)

我很惊讶你没有收到编译器警告,因为我收到了。

【讨论】:

谢谢,对不起,这是一个错字。在代码中我有 num_threads(4) 但仍然没有运气 @Eines He:那很奇怪,因为我粘贴了你的代码,编译并运行它,它可以在所有 4 个内核上运行。 如何设置环境?我认为代码非常基本,不可能出错。我正在使用 g++ 4.6.1 和 libomp1。我认为 openmp 肯定可以工作,因为我在检查 cpus 的数量时没有问题......等等。一定是我没有正确设置环境的地方。 嗯...我在 Windows 上使用 cl.exe 进行了测试。我会尽快在我的 Linux 环境中测试它并通知您。 好的,所以我在 ubuntu 上使用 g++ 4.5.2 进行了测试,它在那里也可以正常工作。【参考方案2】:

我在 Visual Studio 中遇到了这个问题,最后我明白我忘记在 Visual Studio 中启用 Open MP 支持。它没有给我任何错误,而是只为一个线程执行了程序

【讨论】:

supercomputingblog.com/openmp/… 节省了我的时间。谢谢。【参考方案3】:

首先选择项目_>属性->c/c++->语言->打开mp支持->选择yes 然后你会发现上面的一致性模式(设为no)

【讨论】:

【参考方案4】:

在调用 omp 并行部分之前使用函数 omp_set_num_threads(4)。

另外,你如何确定线程数? 将您的 printfs 嵌入到关键部分,以确保打印所有内容。

【讨论】:

【参考方案5】:

当我使用 C 代码扩展 numpy 模块时,我在 ubuntu 桌面上遇到了同样的情况。 openmp 只运行一个线程。我碰巧删除了libopenblas-base并安装了libatlas-base-dev。(处理numpy安装问题)然后多线程openmp回来了:)

我已经在 64 核的 ubuntu 服务器上对其进行了测试,它就像我的桌面一样工作! 我认为这是因为 libopenblas 与 atlas 之类的库发生冲突。

【讨论】:

以上是关于为啥 OpenMP 程序只在一个线程中运行的主要内容,如果未能解决你的问题,请参考以下文章

OpenMP为啥这段程序是死锁?

在 Openmp (C++) 中销毁线程

为啥openmp不根据手动NUMA绑定放置线程?

在visual studio中运行OpenMP并行程序,设置的线程数NUM_THREADS与系统CPU线程数啥关系

使用 openmp 时运行的线程数不一致

如何修复 OpenMP 程序的 gdb 运行中的线程数