【问题标题】:How to identify the bottlenecks preventing my program to scale well on a 32 core CPU? [closed]如何识别阻碍我的程序在 32 核 CPU 上良好扩展的瓶颈? [关闭]
【发布时间】:2019-07-07 07:41:49
【问题描述】:

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

我想确定这个扩展瓶颈的来源。

我想知道可用的技术,以查看在我的代码中是否有任何“热”部分阻止 32 个进程与 12 个进程相比产生显着收益

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

我曾尝试使用 linux perf,但我不确定我应该寻找什么;此外,perf 的 mem 模块在 AMD CPU 上也不起作用。 我也尝试过使用 AMD uProf,但我再次不确定这个系统范围的瓶颈会出现在哪里。

任何帮助将不胜感激。

【问题讨论】:

  • 请花点时间阅读the help pages,尤其是名为"What topics can I ask about here?"的部分。另请阅读how to ask good questions 和this question checklist。最后不要忘记如何创建minimal reproducible example。
  • 看看英特尔 VTune Amplifier 以及带有 cachegrind 的 Valgrind。此外,很高兴看到您强大的缩放数字。 1、2、4、8 等进程的执行时间是什么样的。
  • 好的。我试图编辑这个问题,以便更专注于可用的工具和技术来识别源代码中的瓶颈,以便我可以优化它。问题是这个问题的范围很广,因为我不确定瓶颈在系统规模上的位置。它也可能是一个无法解决的硬件或操作系统限制,我只是不知道。我还添加了一个情节来更好地了解执行时间。
  • 这对我来说是一个相当重要的问题。我很想知道在这个问题上我能做些什么和改进,这样它就不会再被搁置了?
  • 您的程序是否占用大量内存?或者它能否充分利用片上缓存?

标签: c++ performance optimization concurrency profiling


【解决方案1】:

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

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

【讨论】:

  • 谢谢。是的,我猜这个架构是瓶颈的核心。我尝试使用 numactl 为每个进程(以及相应的内存节点)分配一个核心,但没有取得多大成功。对于您的建议 3,我想这更难。这基本上意味着只使用一半的 CPU 内核。
猜你喜欢
  • 2012-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-02
  • 2022-01-06
  • 2019-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多