我正在开发一个高并发的 C 程序,当内核数少于 8 时它可以很好地扩展,但拒绝扩展到超过 8 个内核。
我怀疑内存带宽是瓶颈,我该如何验证这是否属实?
是否有任何工具/技术/操作系统功能可以帮助诊断?
最佳答案
我自己在 NUMA 96x8 内核机器上遇到过这个问题。
90% 的问题出在内存/缓存同步上。如果您频繁调用同步例程(原子、互斥锁),则必须使所有套接字上的相应缓存行无效,从而导致整个内存总线完全锁定多个周期。
您可以通过运行像 Intel VTune 这样的分析器来分析它。或 Perfsuite并让他们记录你的原子需要多长时间。如果您正确使用它们,那么它们应该需要 10-40 个周期。将我的多线程应用程序扩展到 8 个插槽(Intel Xeon 上的 8x8 内核)时,我遇到的最坏情况是 300 个周期。
您可以做的另一个简单的分析步骤是在没有任何原子/互斥体的情况下编译(如果您的代码允许的话)然后在多个套接字上运行它 - 它应该运行得很快(不正确,但很快)。
您的代码在 8 核上运行速度快的原因是英特尔处理器在执行原子操作时使用缓存锁定,只要您将所有代码都保存在同一个物理芯片(套接字)上。如果锁必须进入内存总线 - 这就是事情变得丑陋的时候。
我唯一能建议的是:减少调用原子/同步例程的频率。
至于我的应用程序:我必须实现一个几乎无锁的数据结构,以便将我的代码扩展到一个套接字之外。每个线程都会累积需要锁定的操作并定期检查,轮到他刷新它们了。然后传递一个 token 并轮流刷新同步操作。显然,只有当您在等待时有足够的工作要做时才有效。
关于c - 如何查看内存带宽是否已经成为瓶颈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19238236/