最近终于抽空把内存篇更新完了,我分享出来的这些问题,其实都是我之前没有搞的特别明白的困惑。刚刚开始的时候,可能就是在我脑子里蹦出的一个疑问,比如内存随机IO会比顺序IO慢吗? 为了解开这个疑惑,我曾经在网上各种搜索,也去到过国家图书馆翻书,动手搞代码进行性能测试。最终总算是给了自己一个相对比较满意的答案,终于在今年我抽空给大家分享了出来。
在这个解惑过程中,我越来越深地感受到国内的技术圈的特点。那就是特别热衷于应用层的技术,特别喜欢谈一些新的概念,比如你去一个技术峰会看看,都是各种高大上的概念,不拽几个时髦的名词出来都生怕别人不知道自己技术实力。 这些本身倒没有错,我想说的是大家好像普遍对于底层的一些基础能力不太重视,当我真正想搜寻一些最基础的硬件、Linux内核相关的内容时,发现资料太少,不是很容易获取到。
我是觉得作为一个技术人应该先去扎扎实实的磨练自己底层的知识。这就好比一个武林新人想要成为盖世大侠的话,必须先修炼的是自己的内功,外功呢也重要,不过优先级应该在内功之后。 只有你具备极其深厚的内功,你学习各种新技术,理解各种新概念才能够得心应手。这也是我把我的这些分享命名成《开发者内功修炼》的原因。修建一栋大楼肯定也是从挖地基开始,没见过那栋百米高楼是直接平地开始建的。
按照惯例,再对内存篇所有相关的文章进行一下总结。
1第一部分:物理篇
在这一部分里,分享的三篇文中主要集中在对内存的物理构成理解上。
在这篇文章中,主要目的是借用内存对齐这个技术人耳熟能详的东东来帮助大家理解内存条内部的物理构成,以及内存是怎么配合总线来给CPU传输数据的。
机械硬盘一般我们都知道的随机IO慢的很可怕,因为大家都或多或少有过复制文件特别慢的体验。但是对于内存,绝大部分人就一个印象,快!内存随机IO慢?没听说过。但实际上,内存条的随机IO也比顺序IO慢3-4倍。
这篇文章是为了让大伙明白你的新内存条之所以比较快的原因,内存数据频率是通过技术手段放大出来的。但其实这些放大手段都有一些局限性。比如你的内存数据存储并不连续,这时候DDR2、DDR3的数据预取对你帮助并不大。再比如你的进程数据都存在一个Bank Group里,你的进程内存IO就根本不会达到DDR4厂家宣传的速度。
2第二部分:动手测试
在第一部分里搞清楚一些基本原理后,我又动手搞了一些实际测试。只有你实际操作亲身体会过的东西,才会真正理解。
在这篇文章里我们实验了在各种情况下内存访问延迟的表现。最快的情况下其实不是内存在IO,而是CPU的高速缓存在工作。穿透到内存的话,顺序IO延时大约在10ns左右,随机访问确实比顺序访问慢的多,大概是4倍的关系。
我们在买到一台新服务器的时候,往往厂家会告诉你他家的内存带宽能达到8GB/s、25.6/GB/s。但是在实践中你的内存很难能够达到理想工作状态,考虑到你的访问可能不是顺序IO,内存条存在CL、tRCD、tRP延迟,再加上可能跨QPI总线的延迟。所以你的应用程序里内存的带宽也就达不到厂家的宣称值。我拿一条厂家宣称8.5GB/s的内存条进行测试后发现,最坏情况下其带宽表现只有474M。
不管啥行业的商家都喜欢用理想状态下的值来诱导你进行消费。我又联想到了目前火热的电动汽车的官方宣称续航测试条件,车上只坐一个人,路上没风,路上没坑,匀速运动,不刹车,不加速,汽车周围环境温度要舒适,不能太冷。。。
现代的服务器里,CPU和内存条都有多个,它们之间目前主要采用的是复杂的NUMA架构进行互联,NUMA把服务器里的CPU和内存分组划分成了不同的node。属于同一个node里的CPU和内存之间访问速度会比较快。而如果跨node的话,则需要经过QPI总线,总体来说,速度会略慢一些。。
3第三部分:实践应用
可能很多在应用层做开发的人都或多或少的觉得把内存原理理解到这么底层没有啥必要。因为大家手头的开发工作可能已经被封装过好几层了。首先操作系统就封装了第一层,对用户进程只暴露申请、释放等函数,把高速缓存IO、内存IO都封装成黑盒让你使用。其次现在的开发语言,如PHP、Java等连内存申请、垃圾回收都不用开发者做了,用的时候直接用。
我这里通过三个例子说明一下,如果你能深层次理解硬件、Linux内核工作的话,你对新技术认知的层次,你对手头项目的性能开销的理解都会有极大的帮助。
这里我举了几个PHP7内核里的几个数据结构的优化,因为作者大牛深谙CPU与内存的工作原理,表面上看起来只是几个字节的节约,但是实际上爆发出了巨大的性能提升。
在这篇文章中,通过将内存的离散的随机IO变成顺序IO,让内存工作在最舒服的状态,进而达到了很多倍的读取性能的改进。
哦,等等。差点忘了一个,在NUMA时代的今天,单进程最大可以用到多少内存?传说中的NUMA陷阱长什么样子,《挑战Redis单实例内存最大极限,“遭遇”NUMA陷阱!》来告诉你。
好了,内存篇就给大家分享到这里,接下来我会逐步整理我在硬盘、网络方向的思考再给大伙分享出来,提前祝大家2020年新年快乐!