ECC校验有什么作用
熟悉计算机系统的同学可能都看过带ECC校验的DDR报DDR单bit error或者多bit error,有时候只是报了个单bit error的错,但是对系统整体运行没有影响,有时候报的多了,或者报了多bit error系统就可能直接挂了。那么这其中ECC到底起到了什么样的作用。
先看看另外几种校验算法
奇偶校验(Parity Check)
奇偶校验最初是为了检测内存软错误(内存里面的数据是需要定时充电刷新的,因为内存里面的存储单元会持续放电,导致bit电位产生变化,对于数据来说就是出错了,这个后面可以单独整一篇具体学习下,软错误概率参考如下,十几年前的数据了,现在应该更小),在每个字节(byte)之外额外加了一bit校验位。
对于数据来说,只有0或者1两种状态,假定1个byte数据为1 1 1 1 1 1 0 0,将每一个bit相加(1+1+1+1+1+1+0+0=6),为偶数。如果说采用的是奇校验,则该校验位定为1;如果采用的是偶校验,则该校验位定为0。
总体来说,对于奇校验(保证序列(包括校验位)1的个数为奇数),若数据中有奇数个“1”,则校验结果为0,若数据中有偶数个“1”,则校验结果为1; 对于偶校验(保证序列(包括校验位)1的个数为偶数),若数据中有偶数个“1”,则校验结果为0,若数据中有奇数个“1”,则校验结果为1。
奇偶校验只能够检测错误,无法纠正错误,并且由于其原理特性,无法检测双位错误。
CRC校验(Cyclic Redundancy Check)
循环冗余校验(CRC)具备检错和纠错的能力(其由信息码n位和校验码k位构成),其校验可以理解为一种二进制模2算法,它是一定能被生成多项式整除的,如果除不尽,那就说明传输出现了错误。CRC校验会占用较多CPU,效率不是很高,估计是运算起来比较复杂。
直接上公式说明:
(1)先假定一个多项式,用于计算校验码,设多项式为G(x)=x^2+x+1(G(x)是一个k+1位的二进制数),其二进制表示为111,共3位,其中k=2;
(2)假设要发送数据序列的二进制为10111(即f(x)),共5位;
(3)多项式的位数为3,则在要发送的数据后面加上3-1个位的0(生成f(x)*(x^k)),二进制表示为1011100,共7位;
(4)用生成多项式的二进制表示111去除乘积1011100,按模2算法求得余数序列为01(1.注意余数一定是k位的,如果位数不够,需要在高位补0;2.模2算法是不向上借位的,相当于异或);
(5)将余数添加到要发送的数据后面,得到真正要发送的数据的比特流:1011101,其中前5位为原始数据,后2位为CRC校验码;
(6)接收端在接收到带CRC校验码的数据后,如果数据在传输过程中没有出错,将一定能够被相同的生成多项式G(x)除尽,如果数据在传输中出现错误,生成多项式G(x)去除后得到的结果肯定不为0。
MD5校验(Message-Digest Algorithm 5)
MD5的实际应用是对一段 Message(字节串)产生 fingerprint(指纹),可以防止被“篡改”,一般用于文件加密或者解密,每个文件的MD5都是唯一的(还是会有小概率不唯一的情况,毕竟对一些文件稍微修改checksum不变的情况还是有的),MD5长度为32位的16进制数,换算成二进制就是32*4=128bit。
ECC校验(Error Correcting Code)
ECC 校验感觉与奇偶校验有点类似,本身也是在奇偶校验的基础上发展起来的。与奇偶校验位不同的是,奇偶校验是通过增加1位来检测1byte数据的正确性,也就是每1个byte都需要增加1位来进行检测,当数据位宽比较大的时候,需要的奇偶校验位的位数也会成倍增加;而ECC校验不一样,随着数据位宽的成倍增加,ECC校验位增加的却不是很多(其实我感觉这只是一种说法,ECC本质上也算是奇偶校验,只是校验的方式不一样而已,对于普通奇偶校验来说,我也可以2个byte来增加1位进行检测呀,毕竟程序是我自己写的嘛,不过从协议的角度上讲,那就是一种经过多方综合考虑后约定的关系了)。
ECC 校验能纠正单比特错误和检测双比特错误,但是对 1bit 以上的错误无法纠正,2bit 以上的错误不能检测。从这个角度来看,当系统报多bit错误的时候系统可能会挂掉就不奇怪了,因为纠不回来嘛,但是实际上这也是软件设置的问题,毕竟只是几个数据的错误一般也不会造成系统瘫痪,更多的是一种自我保护机制,万一是硬失效,那不就GG了。
目前服务器上使用的ECC内存指的就是这个,内存条上会有很多DDR颗粒,ECC一般是使用额外的颗粒用于存储校验位。所以ECC内存并不会比普通的内存条更快,人家只是有个检错和纠错机制,可以更稳定而已,加上算法本身的开销,其实速率并没有优势。
关于ECC位宽的说明
目前在网上找了一圈大概有两个版本:
1、当数据位宽只有1个byte的时候,需要5个bit来进行ECC校验,而后数据位宽每增加一倍,ECC只需要增加1bit的校验位,16bit需要6bit ECC,32bit需要7bit ECC,64bit需要8bit ECC。
2、将ECC校验算法分为行校验和列校验,对于512byte数据,1列(8bit)需要6bit的校验位,512行需要18bit行校验位,如下所示:
按上面换算,1byte位宽数据需要6+1=7bit的校验位(大概,如果单行不需要校验的话,那应该是6bit),2byte需要6+2=8bit校验位,4byte需要6+4=10bit校验位,8byte需要6+6=12bit校验位。
3、而实际应用上我也见过32bit数据+8bit ECC校验或者64bit数据+8bit ECC校验。
或许ECC校验只是一个大的类,不同的算法还是存在差异,各种变种啥的,就没做深入了解了,希望有大佬能够直接丢几篇文献给我学习下。