我已经在 4 核(8 线程)笔记本电脑 i7-3920XM 上以这种方式实现了 TBB parallel_for。完成计算大约需要 15s,每个核心的 cpu 使用率约为 70%。如果我为该作业初始化固定数量的线程,例如 g_nthreads = 4,则需要 12 秒。没关系,我对默认方式很满意。
// g_nthreads = 8, on 4-core(8 threads) laptop
int g_nthreads = tbb::task_scheduler_init::default_num_threads();
tbb::task_scheduler_init tbb_init(g_nthreads);
...
// k iterates from 0 to N-1
tbb::parallel_for(0, N, [tool, pos, rock,...] (int k) {
...
Func( tool, pos, k, rock ,...);
}
)
问题是如果我在 20 核(40 线程)工作站 Xeon E5-2680 上使用相同的代码,性能会迅速降级到 30 秒,其中 TBB 自动为作业初始化 40 个线程。在这种情况下,总体 CPU 使用率为 12%,其中只有一半显示为正在运行。当我再次将线程数固定为 4 时,需要 13 秒,但总体 CPU 使用率仍约为 12%。
看起来这项工作不一定需要在 20 核(40 线程)计算机上运行这么多线程,并且将工作划分为 40 个任务的开销决定了性能。
如何在 20 核(40 线程)计算机上为这项工作最大化 CPU 使用率并提高性能?Func()是一个需要大量计算的 EM 函数。
更新:
最后,我在 40 核计算机上实现了 100% CPU 的性能。
1,该程序将线程固定到通常不应该是正确方法的核心。最好让 TBB 自己决定打开内核。
2、强制程序使用tbbmalloc.dll和tbbmalloc_proxy.dll,可以在VS中设置:项目属性--C/C++--高级--强制包含文件-->“tbb/tbbmalloc_proxy.h”。这 2 个 DLL 用于 TBB 内存管理。