如何确定瓶颈,阻止我的程序在32核CPU上很好地扩展?

时间:2019-07-07 07:41:49

标签: c++ performance optimization concurrency profiling

我编写了一个运行良好的程序。我现在想在我们的32核计算机(AMD Threadripper 2990wx,128GB DDR4 RAM,Ubuntu 18.04)上并行运行32个独立实例。但是,在同一台计算机上同时运行约12个进程后,性能提升几乎为零。我现在需要对此进行优化。这是平均加速的曲线图:

Poor concurrent scaling on a 32 core AND Threadripper CPU

我想确定此扩展瓶颈的根源。

我想了解可用的技术,以便在我的代码中查看是否有“热”部分阻止32个进程比12个进程产生可观的收益

我的猜测是它与内存访问和NUMA体系结构有关。我尝试使用numactl进行实验,并为每个过程分配了一个核心,但没有明显的改进。 该应用程序的每个实例最多使用大约1GB的内存。它用C ++编写,没有“并行代码”(没有线程,没有互斥体,没有原子操作),每个实例都是完全独立的,没有进程间通信(我只是通过bash脚本以nohup开头) 。该应用程序的核心是基于代理的模拟:许多对象是逐步创建的,彼此交互并定期更新的,这可能不是非常友好的缓存。

我尝试使用linux perf,但是我不确定应该寻找什么。同样,perf的内存模块在AMD CPU上不起作用。 我也尝试过使用AMD uProf,但是我不确定这个系统范围的瓶颈会出现在哪里。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

问题可能出在Threadripper体系结构上。它是32核CPU,但是这些核分布在4个NUMA节点中,其中一半没有直接连接到内存。因此,您可能需要

  1. 为所有进程设置处理器亲和力,以确保它们永远不会在内核之间跳转
  2. 确保在正常NUMA节点上运行的进程仅访问直接连接到该节点的内存
  3. 减少位于受损NUMA节点上的核心上的负载

enter image description here