在开始今天的分享之前,我先给大家看两个 1R * 8 的内存条。
现在的 CPU 都是 64 位的,每次和内存通信都要传输 64 比特的数据。1R * 8 类型的内存中的 1R 指的是该内存条只有一个 rank,8 指的是在每一次 64 比特的内存 IO 过程中,每个内存颗粒分别提供 8 比特的数据。这样计算一下,64 比特的数据就需要 8 个内存颗粒共同来组成。
这两个内存条中,为什么一个是 8 个颗粒,另一个是 9 个颗粒呢?这个故事还要从比特翻转说起。
一、比特翻转和 ECC 内存
我们的电脑在运行的时候,CPU 一直都需要和内存进行数据交互。但在交互的过程中,由于周围电磁场的干扰,会有概率发生比特翻转。
图片
据统计,一根 8 GB 的内存条平均大约每小时会出现 1 - 5 个这样的错误。
图片
我们使用个人电脑在办公的时候,由于内存主要都用来处理图片、视频等数据。即使内存出现了比特翻转,可能影响的只是一个像素值,很难感觉出来,没有太大的影响。即使是比特翻转真的发生在关键的系统代码导致运行出问题,也不是什么大事,重启一次就解决了。
但在服务器应用中,处理的一般都是非常重要的计算,可能是一笔订单交易,也可能是一笔存款。另外就是服务器经常是连续要运行几个月甚至是几年,没有办法通过重启的方式来解决问题。因此服务器对比特翻转错误的容忍度很低。需要有技术方案能够一定程度解决比特翻转问题所带来的影响。
ECC 就是这样一种内存技术。它的英文全称是 “Error Checking and Correcting”,对应的中文名称就叫做“错误检查和纠正”。从它的名称中我们可以看出,ECC 不但能发现内存中的错误,而且还可以进行纠正。
相比没有使用 ECC 技术的个人电脑内存,内存颗粒中全部都用来存储数据即可。在 ECC 内存中每 64 比特的数据都需要额外的 8 比特数据作为校验位,用来辅助发现或者纠正错误。
图片
所以,开篇的问题我们就有答案了。普通的内存条中全部颗粒都用来存储真正的数据。而 ECC 内存中除了数据外,还需要存储 8 比特的校验位。
在普通的 1R * 8 的内存中需要 64 / 8 = 8 个颗粒就够了。但是 ECC 内存中一次 IO 要传输 72 比特的数据,所以总共需要 72 / 8 = 9 个内存颗粒。
问题已经弄明白了。但是咱们「开发内功修炼」公众号的风格是不光要知道,还要弄懂原理。所以我们再接着看 ECC 纠错算法是如何工作的。
二、ECC 纠错原理
那么为什么 ECC 内存有了额外的 8 比特的冗余校验数据就能够发现和纠正错误了呢?我们先来看下最简单的奇偶校验。