54 | 理解Disruptor(上):带你体会CPU高速缓存的风驰电掣
该思维导图由 AI 生成,仅供参考
Padding Cache Line,体验高速缓存的威力
- 深入了解
- 翻译
- 解释
- 总结
Disruptor框架是一个由高频交易公司LMAX开源的项目,旨在充分利用CPU和高速缓存的硬件特性,以追求极限性能。尽管使用的是性能受限的Java语言,但通过对硬件层面原理的理解,Disruptor成功将CPU性能发挥到极限。通过缓存行填充技术和RingBuffer数据结构,Disruptor优化了CPU Cache的访问速度,提高了数据访问速度和程序运行效率。Disruptor的设计思路贯穿始终,旨在充分利用硬件特性,以实现高性能的生产者-消费者模型。文章还介绍了Disruptor的官方文档和源代码,推荐读者深入学习。欢迎读者尝试修改Disruptor的代码,探索缓存行填充对性能的影响,并分享测试结果。
《深入浅出计算机组成原理》,新⼈⾸单¥68
全部留言(22)
- 最新
- 精选
- 小海海老师,有个疑惑的地方:文中讲了RingBuffer类利用缓存行填充来解决INITIAL_CURSOR_VALUE伪共享的问题,但是我记得Java对象内存布局是:实例变量放在堆区,静态变量属于类,放在方法区,而堆区和方法区在内存里肯定是隔离开的,但是RingBuffer的前后填充字段都是实例字段,而INITIAL_CURSOR_VALUE是静态常量,所以实际运行中他们肯定不是紧密排列在一起的,那么就解决不了伪共享的问题了,况且RingBuffer的子类RingBufferFields还有其他实例字段,如:indexMask、entries、bufferSize、sequencer,这些字段都是final修饰的,即对象构建后不会再修改,所以我理解前后的缓存行填充守护的应该是这几个字段,而且从子类RingBufferFields的命名也可以看出前面那几个字段才是想要缓存的字段。希望得到老师的回复,另外课程快结束了,一路跟下来收获很大,我准备这段时间二刷来巩固下^_^
作者回复: 我回头重新看了一下代码,我觉得你说的是对的,Padding对应的是RingBufferFields里面的字段,而不应该是INITIAL_CURSOR_VALUE,我去订正一下。
2019-09-09448 - 山间竹在java8中,jvm团队搞出了@Contended注解来进行支持,在你需要避免“false sharing”的字段上标记注解,这可以暗示虚拟机“这个字段可以分离到不同的cache line中”,这是JEP 142的目标。
作者回复: 👍
2020-01-0639 - D这个是不是和前面讲的msei有一定关系啊,请徐老师点拨
作者回复: 没错,看来你读的时候很仔细地思考过。 当我们的对于数据修改,修改了cache之后,这个数据如果要同步到主内存,那么就会需要通过MSEI协议来在各个CPU Core的Cache里面保持数据同步。 那么是否需要同步主内存,会引发另外一个知识点,就是Memory Barrier/Fence,这部分知识点其实还可以单独拿来说两讲。你可以先去搜索上面的关键词,了解一下。
2019-09-06223 - -_-|||“而 Disruptor 很取巧地在需要频繁高速访问的变量,也就是 RingBufferFields 里面的 indexMask 这些字段前后,各定义了 7 个没有任何作用和读写请求的 long 类型的变量。”为什么前后各7个,cache line 就没有写的请求,就是因为8个long正好64byte吗,为什么没有写的呢?
作者回复: -_-_aaa 同学, 你好,indexMask是一个第一次写入之后就不变动的变量了。你可以看到在代码里面这是一个Java的final变量。 前后7个就是因为8个long正好64byte,这样cache line无论在哪个位置被加载,这64个byte在第一次加载到cache line之后就不再需要更新了。
2020-01-31520 - leslie老师今天说的这个东西其实就是MQ:只不过现在的MQ基本上是在充分利用内存/缓存,而disruptor其实是在利用CPU cache。刘超老师有一点确实没有说错“计算机组成原理和操作系统相辅相成”:学到今天去相互结合确实发现这种收益远比单独学习好。 扩展的问老师一个问题:现在所谓的智能芯片或者说前端时间提出的智能芯片,会对后续产生革命性影响么?毕竟硬件的i5到现在差不多十多年了其实进步不大,这十余年最大的变化莫过于内存容量的暴涨造就了nosql、MQ的兴起,如果说将来cache的变化是吧同样可能早就类似于老师今天所说的Disruptor这种基于CPU Cache技术的兴起。 今年华为的AI CPU、老美那边的云计算CPU似乎实验室测试已经通过了:毕竟从奔腾4之后到现在近20年了,老师今天所说的又刚好符合现在关键硬件CPU的革新时期?老师对此是如何看待?希望老师能提点。
作者回复: 提点谈不上,对于芯片和硬件我连从业者都还算不上。 不过过去几年的繁荣主要是来自于Intel CPU的极限性能提升已经到头了。所以反而大家回头去找其他的解决方案,在体系结构层面又有了很多新的机会。 我觉得大家都可以去读一读 David Patterson 老爷爷的 <计算机体系结构新黄金时代:历史、挑战和机遇> 这个访谈 https://www.bilibili.com/video/av46710093/
2019-09-06217 - Scott最好说明一下,这种填充cache line的手法是为了防止False Sharing
作者回复: 是的,篇幅有限,所以没有太具体解释False Sharing和Memory Fence,欢迎大家留言分析这两部分知识点。
2019-09-0613 - 易儿易经典的东西总是容易被频繁引用,disruptor记得没错应该是在java并发实战专栏里被王宝令老师讲过,今天又一次学习,加深了印象……拍个双响马屁:两位老师都有很高的水准,深入浅出!
作者回复: 谢谢支持。Disruptor在2011年开源的时候其实是让很多Java开发同学们感到惊艳的,是很值得仔细研读的一份代码
2019-09-087 - -_-|||“我们现在的 64 位 Intel CPU 的计算机,缓存行通常是 64 个字节(Bytes)”,64位为什么不是64bit而是设计成64Byte的缓存行,感觉应该叫64比特intel CPU的计算机。
作者回复: -_-_aaa同学, 你好,64位是内存寻址空间,通常也是数据通路的字长(word size) 这个和缓存行之间没有对应关系。 我们也可以把缓存行设计成 16个word,也就是128 Bytes,但是并不会叫他128位计算机。
2020-01-311 - 许童童老师讲得实在是太好了。
作者回复: 谢谢支持
2019-09-071 - 等风来老师, 我对于前后7个long有点疑惑, 我大概知道是为了防止被换出, 但就是不知道为什么可以😂, 可以举例说明一下吗2019-10-1023