【发布时间】:2018-08-12 19:28:06
【问题描述】:
我正在开发一个最初为多核处理器系统开发的遗留应用程序。为了利用多核处理,已使用 OpenMP 和 PPL。 现在一项新要求是在具有多个 NUMA 节点的系统上运行该软件。目标操作系统是 Windows 7 x64。
我进行了几次测量,发现在将应用程序分配给单个 NUMA 节点时执行时间已达到最佳状态,因此浪费了一个完整的处理器。应用程序的许多部分执行数据并行算法,例如并行处理向量的每个元素,并将结果写入另一个向量,如下例所示
std::vector<int> data;
std::vector<int> res;
// init data and res
#pragma omp parallel for
for (int i = 0; i < (int) data.size(); ++i)
{
res[i] = doExtremeComplexStuff(data[i]);
}
据我所知,此类算法的性能下降是由第二个 NUMA 节点的非本地内存访问引起的。所以问题是如何让应用程序性能更好。
是否以某种方式透明地加速了对非本地内存的只读访问(例如,通过操作系统将数据从一个节点的本地内存复制到另一个节点的本地内存)? 我是否必须拆分问题大小并将输入数据复制到相应的 NUMA 节点,对其进行处理,然后再次合并所有 NUMA 节点的数据以提高性能?
如果是这种情况,是否有 std 容器的替代品,因为它们在分配内存时不支持 NUMA?
【问题讨论】:
-
我刚好在浏览器中打开了这篇论文:cs.brown.edu/~irina/papers/asplos2017-final.pdf
-
您尝试过不同的
numactl策略吗?numactl --interleave=all有时会有所帮助。 -
您在询问操作系统 numa 策略时甚至没有告诉我们您的操作系统(版本)、有关您的硬件的任何信息,并且只提供极少的关于您的代码的信息。任何答案都必须对您的设置进行疯狂的猜测。你的测量是一个好的开始,但你必须更深入地挖掘才能真正查明瓶颈。即使是关于 NUMA 处理最佳实践的精彩而详细的答案也可能对您没有丝毫帮助......
-
请注意,如果您的所有循环都像您描述的那样,那么您将没有 NUMA 问题,因为 OpenMP 保证重复循环,即使具有不同的主体,将在线程之间以相同的方式分配索引,如果大小是一样的。
-
@Tyson 不幸的是我没有想出更好的解决方案。在我的情况下,两个多线程、重负载应用程序同时运行,因此我将每个进程的线程亲和性分别设置为一个 NUMA 节点。因此,每个进程的线程都被排他地调度到一个 NUMA 节点。这在不修改任何现有代码库的情况下提供了更好的整体性能。
标签: c++ parallel-processing openmp numa