关于linux:带你深入理解内存对齐最底层原理

6次阅读

共计 1387 个字符,预计需要花费 4 分钟才能阅读完成。

置信绝大多数的人都理解内存对齐,都晓得变量应该按 8 字节去对齐,这样性能高。然而其最最底层的原理是啥呢?有的人可能会说,因为高速缓存是以 8 字节为单位进行的。读者你很聪慧,这是起因之一。但我明天想挖的是更底层一点的原理,让咱们去内存的物理形成里找找答案!

内存物理构造

后面咱们说过内存是由 chip 形成。每个 chip 外部,是由 8 个 bank 组成的。其结构如下图:

而每一个 bank 是一个二维立体上的矩阵,后面文章中咱们说到过。矩阵中每一个元素中都是保留了 1 个字节,也就是 8 个 bit。

内存编址形式

那么对于咱们在应用程序中内存中地址间断的 8 个字节, 例如 0x0000-0x0007,是从位于 bank 上的呢?直观感觉,应该是在第一个 bank 上吗?其实不是的,程序员视角看起来间断的地址 0x0000-0x0007,实际上位 8 个 bank 中的,每一个 bank 只保留了一个字节。在物理上,他们并不间断。下图很好地论述了理论状况。

你可能想晓得这是为什么,起因是电路工作效率。内存中的 8 个 bank 是能够并行工作的。如果你想读取址 0x0000-0x0007,每个 bank 工作一次,拼起来就是你要的数据,IO 效率会比拟高。但要存在一个 bank 里,那这个 bank 只能本人干活。只能串行进行读取,须要读 8 次,这样速度会慢很多。

论断

所以,内存对齐最最底层的起因是内存的 IO 是以 8 个字节 64bit 为单位进行的。 对于 64 位数据宽度的内存,如果 cpu 也是 64 位的 cpu(当初的计算机根本都是这样的),每次内存 IO 获取数据都是从同行同列的 8 个 chip 中各自读取一个字节拼起来的。从内存的 0 地址开始,0- 7 字节的数据能够一次 IO 读取进去,8-15 字节的数据也能够一次读取进去。

再换个例子如果你指定要获取的是 0x0001-0x0008,也是 8 字节,然而不是 0 结尾的,内存须要怎么工作呢?没有好方法,内存只好先工作一次把 0x0000-0x0007 取出来,而后再把 0x0008-0x0015 取出来,把两次的后果都返回给你。CPU 和内存 IO 的硬件限度导致没方法一次跨在两个数据宽度两头进行 IO。这样你的应用程序就会变慢,算是计算机因为你不懂内存对齐而给你的一点点惩办。

扩大 1:事实上,编译和链接器会主动替开发者对齐内存的,尽量帮你保障一个变量不跨列寻址。然而他不能做到非常完满。

扩大 2:其实在内存硬件层上,还有操作系统层。操作系统还治理了 CPU 的一级、二级、三级缓存。不晓得你有没有印象,咱们后面的文章说过高速缓存里的 Cache Line 也是 64 字节,它是内存 IO 的整数倍,不会让内存 IO 节约。



开发内功修炼之内存篇专辑:

  • 1. 带你深刻了解内存对齐最底层原理
  • 2. 内存随机也比程序拜访慢,带你深刻了解内存 IO 过程
  • 3. 从 DDR 到 DDR4,内存外围频率其实基本上就没太大的提高
  • 4. 理论测试内存在程序 IO 和随机 IO 时的拜访延时差别
  • 5. 揭穿内存厂家“谎话”,实测内存带宽实在体现
  • 6.NUMA 架构下的内存拜访提早区别!
  • 7.PHP7 内存性能优化的思维精华
  • 8. 一次内存性能晋升的我的项目实际
  • 9. 挑战 Redis 单实例内存最大极限,“遭逢”NUMA 陷阱!

我的公众号是「开发内功修炼」,在这里我不是单纯介绍技术实践,也不只介绍实践经验。而是把实践与实际联合起来,用实际加深对实践的了解、用实践进步你的技术实际能力。欢送你来关注我的公众号,也请分享给你的好友~~~

正文完
 0