系统性能调优必知必会
陶辉
智链达 CTO,前阿里云 P8 高级技术专家
36367 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
系统性能调优必知必会
15
15
1.0x
00:00/00:00
登录|注册

01 | CPU缓存:怎样写代码能够让CPU执行得更快?

显式预测分支概率
分支预测器
CPU Cache Line
二维数组遍历
三级缓存
二级缓存
一级缓存
多线程并行访问相邻变量的CPU缓存失效问题
进程/线程绑定
指令缓存命中率
数据缓存命中率
多级缓存
思考题
多核CPU下的缓存命中率
缓存命中率优化
CPU缓存结构
CPU缓存优化

该思维导图由 AI 生成,仅供参考

你好,我是陶辉。
这是课程的第一讲,我们先从主机最重要的部件 CPU 开始,聊聊如何通过提升 CPU 缓存的命中率来优化程序的性能。
任何代码的执行都依赖 CPU,通常,使用好 CPU 是操作系统内核的工作。然而,当我们编写计算密集型的程序时,CPU 的执行效率就开始变得至关重要。由于 CPU 缓存由更快的 SRAM 构成(内存是由 DRAM 构成的),而且离 CPU 核心更近,如果运算时需要的输入数据是从 CPU 缓存,而不是内存中读取时,运算速度就会快很多。所以,了解 CPU 缓存对性能的影响,便能够更有效地编写我们的代码,优化程序性能。
然而,很多同学并不清楚 CPU 缓存的运行规则,不知道如何写代码才能够配合 CPU 缓存的工作方式,这样,便放弃了可以大幅提升核心计算代码执行速度的机会。而且,越是底层的优化,适用范围越广,CPU 缓存便是如此,它的运行规则对分布式集群里各种操作系统、编程语言都有效。所以,一旦你能掌握它,集群中巨大的主机数量便能够放大优化效果。
接下来,我们就看看,CPU 缓存结构到底是什么样的,又该如何优化它?

CPU 的多级缓存

刚刚我们提到,CPU 缓存离 CPU 核心更近,由于电子信号传输是需要时间的,所以离 CPU 核心越近,缓存的读写速度就越快。但 CPU 的空间很狭小,离 CPU 越近缓存大小受到的限制也越大。所以,综合硬件布局、性能等因素,CPU 缓存通常分为大小不等的三级缓存。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了CPU缓存的结构和运行规则,以及如何通过优化代码来提升CPU缓存的命中率,从而优化程序性能。首先,文章详细介绍了CPU的多级缓存结构,包括一级、二级和三级缓存的特点和作用,强调了缓存命中率对程序性能的影响,以及指令缓存和数据缓存的区别。其次,通过具体的例子,阐述了如何通过优化代码来提升CPU缓存的命中率,从而提高程序性能。例如,通过调整数据的访问顺序来提升数据缓存的命中率,以及通过合理的代码编写来提升指令缓存的命中率。最后,文章还介绍了在实际应用中如何利用工具来验证缓存命中率,以及如何利用编译器提供的工具来优化代码的性能。通过本文的阅读,读者可以深入了解CPU缓存的工作原理和优化方法,从而能够更有效地编写优化性能的代码。文章还提到了多核CPU下的缓存命中率的问题,以及如何通过绑定进程或线程到特定CPU核心来提升缓存命中率。总的来说,本文为读者提供了深入了解CPU缓存工作原理和优化方法的重要知识,对于希望优化程序性能的开发人员具有重要的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《系统性能调优必知必会》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(95)

  • 最新
  • 精选
  • 忆水寒
    因为在多核CPU时代,CPU有“缓存一致性”原则,也就是说每个处理器(核)都会通过嗅探在总线上传播的数据来检查自己的缓存值是不是过期了。如果过期了,则失效。比如声明volitate,当变量被修改,则会立即要求写入系统内存。

    作者回复: 讲得非常好!忆水寒同学对底层知识理解地很透彻!

    2020-04-27
    4
    91
  • 二星球
    一片连续的内存被加载到不同cpu核心中(就是同一个cache line在不同的cpu核心),其中一个cpu核心中修改cache line,其它核心都失效,加锁也是加在cache line上,其它核心线程也被锁住,降低了性能。解决办法是填充无用字节数,使分开

    作者回复: 完全正确!二星球同学用过填充法写代码么?或者看到过这样的开源代码?

    2020-04-27
    12
    76
  • 配置 nginx server_names_bucket_siz 的大小 而桶大小为 50 字节,会导致最坏 2 次访问内存,而 70 字节最坏会有 3 次访问内存。 ---------------------------------------------------- 为什么 50字节会访问2次内存呢? 不是可以加载 64k数据到缓存,包含了 50个字节,一次不就够了吗? 70k 也是同样的问题,为什么是3次啊

    作者回复: 你好一步,这里的原理其实与思考题是一致的,因为当所有bucket连续时,某个50字节的bucket一定会横跨2个cpu cache line,比如第2个bucket在内存上占用50-100字节,这样当CPU1访问第1个bucket时,会把第2个bucket的数据也载入,这样CPU2访问第2个bucket时,若第1个bucket发生变化,就会导致CPU2必须重新读入bucket。类似的,某个70个字节的bucket一定会占用到3个cpu cache line。文章中写得不够细,我再稍微调整补充下好了。

    2020-04-28
    43
  • 忆水寒
    这个文章其实讲解的很细致,来龙去脉都说清楚了。不错! 其实每篇文章能讲到这个地步,作为读者(也可以称为学生)每篇能够学到一个哪怕很小的知识点,那也是值得的。

    作者回复: 最初这篇文章有6千字,想在一篇文章中讲清楚CPU缓存太难啦,后来编辑小姐姐协助我一点点删下来,还是担心读者看不懂,找不到重点。 忆水寒同学的知识很扎实,你点赞我就放心啦^_^。

    2020-04-27
    3
    28
  • xzy
    思考题: 数据从内存加载到高速缓存中,以块为基本单元(一个块64字节),相邻的两个变量很可能在同一块中,当这个数据块分别加载到两颗cpu的高速缓存中时,只要一个cpu对该块(高速缓存中缓存的块)进行写操作,那么另一cpu缓存的该块将失效。 可以通过将两个变量放到不同的缓存块中,来解决这个问题

    作者回复: 是的,路阳同学思路完全正确!

    2020-04-27
    8
    25
  • 长脖子树
    多线程并行访问不同的变量, cpu 缓存的失效需要基于其中有一个 core 将 L1/L2 cache 写回主存, 但这个时间是不固定的. 除非你使用 lock 等强制刷新到 主存 , 而其他 core 上的缓存行会置为 Invalid , 这就要提到 缓存一致性 MESIF 协议 如果这些变量在内存布局中相邻的, 很有可能在同一个 cache line 中, 要避免竞争, 就要避免在同一个 缓存行中, 比如 java 中的方法: 手动在这个变量前后 padding 间隔开一定字节(一般 64 字节) 或者 @Contended 标记这个变量

    作者回复: 你好长脖子树,你的答案完全正确,而且非常详细,长脖子树提到的Intel MESIF 协议,以及Java中的@Contended注解非常专业,请其他同学参考!!

    2020-04-28
    5
    21
  • 海罗沃德
    第一篇就进入知识盲区了

    作者回复: 你好海罗,这门课虽然只有30讲,但会涵盖绝大部分性能优化点,所以每篇文章都会涉及不同的知识。这一篇我希望你能明白CPU缓存的用途,这是成为高手必须了解的知识。 比如,我在protobuf那一讲中,还会讲到protobuf是怎么利用缓存的。所以,你可以先有这么一个概念,在后续用到的时候,再回过头来看,就更容易理解了。

    2020-04-27
    20
  • 好吃不贵
    思考题猜测是False sharing导致的,非常热的数据最好cache line对齐。

    作者回复: 是的,好吃不贵的答案更加简洁!

    2020-04-28
    14
  • AI
    CPU性能优化的4个点: 1.按顺序访问数据(操作连续内存):利用数据缓存,提高读数据缓存的命中率。 2.有规律的条件分支(如数据集先排序再处理):利用指令缓存,提高读指令缓存的命中率。 3.数据按缓存行大小填充/对齐(通常为64字节):防止伪共享,提高并发处理能力和缓存命中率。 4.对于多核处理器,如果缓存命中率很高,可以考虑进行CPU绑定。

    作者回复: 谢谢二进制之路的全面总结!

    2020-05-25
    12
  • 鲤鲤鱼
    陶老师我们集群有一个问题,某一台物理机的CPU会被Hadoop yarn的查询任务打满,并且占用最多的pid在不停的变化,我查看了TIME_WAIT的个数好像也不是很多,在顶峰的时候还没达到一万,能够持续一两个小时。这个问题您有没有什么思路呢?

    作者回复: 解决性能问题,一般有两种方法:经验派和“理论”派,前者就是基于自己的经验概率,将能想到的优化方法都试一遍,这种方式通常又有效又快速,但无法解决复杂的问题。 所谓理论派,就是沿着固定的思路,使用二分法,从高至低慢慢下沉到细节。具体到你的问题,我建议你先看看,CPU占用是用户态还是系统态,用户态的话就要分析代码了,系统态还要进一步分析。火焰图通常是个很好的办法,虽然搭能画火焰图的环境很麻烦,但这种底层方法很有效的。

    2020-04-27
    3
    9
收起评论
显示
设置
留言
95
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部