如何识别阻碍我的程序在 32 核 CPU 上良好扩展的瓶颈? [关闭]

Posted

技术标签:

【中文标题】如何识别阻碍我的程序在 32 核 CPU 上良好扩展的瓶颈? [关闭]【英文标题】:How to identify the bottlenecks preventing my program to scale well on a 32 core CPU? [closed] 【发布时间】: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 等进程的执行时间是什么样的。 好的。我试图编辑这个问题,以便更专注于可用的工具和技术来识别源代码中的瓶颈,以便我可以优化它。问题是这个问题的范围很广,因为我不确定瓶颈在系统规模上的位置。它也可能是一个无法解决的硬件或操作系统限制,我只是不知道。我还添加了一个情节来更好地了解执行时间。 这对我来说是一个相当重要的问题。我很想知道在这个问题上我能做些什么和改进,这样它就不会再被搁置了? 您的程序是否占用大量内存?或者它能否充分利用片上缓存? 【参考方案1】:

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

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

【讨论】:

谢谢。是的,我猜这个架构是瓶颈的核心。我尝试使用 numactl 为每个进程(以及相应的内存节点)分配一个核心,但没有取得多大成功。对于您的建议 3,我想这更难。这基本上意味着只使用一半的 CPU 内核。

以上是关于如何识别阻碍我的程序在 32 核 CPU 上良好扩展的瓶颈? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Postgres 恒定 30% 的 CPU 使用率

Linux的中断

国产32核服务器CPU验证成功!100%自主指令架构,单机最多可支持四路128核,来自龙芯中科...

我的多线程游戏一直处于 100% CPU。如何管理线程活动以减少 CPU 负载?

线程数是啥

程序的进程