
当我们的多线程程序遇到性能问题时,通常我们会下意识地觉得这是由于上下文切换、cpu 迁移等因素导致的。那么,如何更进一步地分析究竟是哪一部分语句造成了什么样的影响呢?这篇分享将从计算机体系结构的角度,结合非常典型的代码案例,为你解惑。
在进入正题之前,如果对缓存还不了解的读者,可以先看看这篇分享。
DeepRoute Lab | 【C++性能】CPU Cache Serial 1
01
引子
1.1 第一个代码片段

(点击查看大图)
1.2 第二个代码片段

(点击查看大图)
1.3 转置
代码片段一里面,GoodWorker的效率(计算的耗时)

是 BadWorker 的 10 倍左右(取决于具体硬件条件和其他相关因素)。

在不知道其他背景知识的前提下,我们怎么来定位这个问题呢?
-
加耗时的打印?
- 不好意思,面对这种已经只剩大量基本操作的代码,没法做到更细粒度的耗时打印了。
-
看火焰图?


(点击查看大图)
可以看到,除了 GoodWorker 在整个 workload 上的占比(83%)比 BadWorker (96%) 略低以外(也不能提供其他进一步的指导意义了), 两个函数在火焰图上都可谓是“一马平川”,火焰图在这种情况下也失去了指导意义。
难道就没有任何办法了吗?
开什么玩笑,如果没有办法,这篇文章也就写不下去了!
那么答案是什么呢!
02
Perf Events 初探
2.1 代码片段一的性能数据
在详细介绍 perf events 之前,让我们直观地通过数据来体会一下它在分析这类问题上的强大之处。
下面所有类似的结果均采用 perf events 生成。


(点击查看大图)
以上分别是 BadWorker 和 GoodWorker 使用 Perf Events 诊断的结果,可以看到已经有大量的差异巨大的数值和比例了。
我们通过一个表格对比一下几个主要的指标:

本文深入探讨了缓存对多线程程序性能的影响,通过代码案例和Perf Events工具,揭示了false sharing等问题导致的性能下降。通过分析Perf Events数据,展示了如何定位和理解性能瓶颈,强调了在多线程编程中关注内存布局和临界区设置的重要性。
最低0.47元/天 解锁文章
2291

被折叠的 条评论
为什么被折叠?



