c++ - OpenMP:不要使用超线程内核(一半 `num_threads()` w/超线程)

标签 c++ openmp hyperthreading cpu-cores g++-4.7

Is OpenMP (parallel for) in g++ 4.7 not very efficient? 2.5x at 5x CPU ,我确定当使用默认的 #pragma omp parallel for 时,我的程序的性能在 11s 和 13s 之间变化(大多数总是高于 12s,有时慢到 13.4s),CPU 使用率约为 500%,在 4 核 8 线程 Xeon 上,OpenMP 加速仅为 2.5 倍,在 5 倍 CPU w/g++-4.7 -O3 -fopenmp 上。

我尝试使用 schedule(static) num_threads(4),并注意到我的程序总是在 11.5 秒到 11.7 秒(总是低于 12 秒)内完成,CPU 使用率约为 320%,例如,运行更多始终如一,并且使用更少的资源(即使最佳运行比使用超线程的罕见异常值慢半秒)。

是否有任何简单的 OpenMP 方法来检测超线程,并将 num_threads() 减少到实际的 CPU 内核数?

(有一个类似的问题,Poor performance due to hyper-threading with OpenMP: how to bind threads to cores,但在我的测试中,我发现仅仅从 8 个线程减少到 4 个线程已经以某种方式在 Debian 7 wheezy 和 Xeon E3-1240v3 上完成了 g++-4.7 的工作,所以,这个问题只是关于将 num_threads() 减少到核心数。)

最佳答案

如果您在 Linux 下运行 [也假设是 x86 arch],您可以查看 /proc/cpuinfo。有两个字段cpu coressiblings。第一个是 [真实] 内核的数量,后者是超线程的数量。 (例如,在我的系统上,对于我的四核超线程机器,它们分别是 4 和 8)。

因为 Linux 可以检测到这一点 [并从 Zulan 评论中的链接],也可以从 x86 cpuid 指令中获得该信息。

无论哪种方式,还有一个环境变量:OMP_NUM_THREADS 与启动器/包装器脚本结合使用可能更容易

您可能希望考虑的一件事是,超过一定数量的线程,您可以使内存总线饱和,并且线程 [或核心] 的增加不会提高性能,实际上可能会降低性能。

来自这个问题:Atomically increment two integers with CAS有一个来自 CppCon 2015 的视频谈话的链接,它分为两部分:https://www.youtube.com/watch?v=lVBvHbJsg5Yhttps://www.youtube.com/watch?v=1obZeHnAwz4

每个大约 1.5 小时,但是,IMO,非常值得。

在演讲中,演讲者[做了很多多线程/多核优化] 说,根据他的经验,内存总线/系统在大约四个线程后趋于饱和。

关于c++ - OpenMP:不要使用超线程内核(一半 `num_threads()` w/超线程),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36958661/

相关文章:

c++ - GCC:抱歉,未实现:64 位模式未编译

c++ - C++中文本文件和二进制文件之间的转换

c++ - 使用 OpenMP 并行化 for 循环

c - 在 C 中使用 openMP 并行化函数

c# - 是否有一个任务调度程序非常适合在具有超线程的处理器上进行浮点计算?

C++ 状态 : Sequence of Events is not very object orientated

c++ - 包含<sstream>时是否自动包含<string>

c++ - 通常减少 cv::Mat 或 cv::Mat 的 vector

performance - 生产者-消费者在超同级与非超同级之间共享内存位置的延迟和吞吐量成本是多少?

c# - 为什么完全由CPU约束的进程与超线程一起工作会更好?