我试图了解使用OpenMP(在Windows上)的一个C ++应用程序的巨大性能问题。申请结构如下:
我有一个算法,它基本上由一些使用OpenMP并行化的for循环组成:
void algorithm()
{
#pragma omp parallel for numThreads(12)
for (int i=0; ...)
{
// do some heavy computation (pure memory and CPU work, no I/O, no waiting)
}
// ... some more for-loops of this kind
}
应用程序从n
个不同的线程并行执行此算法n
次:
std::thread t1(algorithm);
std::thread t2(algorithm);
//...
std::thread tn(algorithm);
t1.join();
t2.join();
//...
tn.join();
// end of application
现在,问题如下:
n=1
(只有一次调用algorithm()
)运行具有32个物理CPU内核(没有超线程)的应用程序时,需要大约5秒并将CPU加载到大约30%正如预期的那样(假设我告诉OpenMP只使用12个线程)。n=2
运行时,CPU负载上升到大约60%,但应用程序需要大约10秒钟。 这意味着几乎不可能并行运行多个算法实例。 当然,仅此一点可能有很多原因(包括缓存未命中,RAM带宽限制等),但有一件事让我感到震惊:
n=1
,两个进程在大约5秒后完成,意味着我能够并行运行两个算法,因为他们生活在不同的过程中。这似乎排除了此性能瓶颈的许多可能原因。事实上,即使在分析代码之后,我也无法理解其原因。我怀疑的是,不同并行部分之间的OpenMP可能存在一些过度同步。
有没有人见过这样的效果?或者任何人都可以给我建议如何处理这个问题?我真的已经达到了我所能想到的一切,但到目前为止没有任何成功。我很感激能得到的任何帮助!
非常感谢,
达
PS: