奇偶校验|ECC内存|海明码

news2024/9/21 14:33:46

前言

大家好,我是jiantaoyab,本篇文章给大家介绍数据出错和有什么方法能减少出错。

单比特翻转

由于硬件故障或其他原因,内存或其他存储设备中的单个比特位发生随机变化的现象。

例如,原本存储为1的位可能变为0,或者原本存储为0的位可能变为1。这种错误可能导致程序执行错误或数据损坏。

奇偶校验和校验位

其实,内存里面的单比特翻转或者错误,并不是一个特别罕见的现象。无论是因为内存的制造质量造成的漏电,还是外部的射线,都有一定的概率,会造成单比特错误。而内存层面的数据出错,软件工程师并不知道,而且这个出错很有可能是随机的。

可以用奇偶检验来发现这些错误,奇偶校验的思路很简单。把内存里面的 N 位比特当成是一组。

常见的,比如 8 位就是一个字节。然后,用额外的一位去记录,这 8 个比特里面有奇数个 1 还是偶数个 1。如果是奇数个 1,那额外的一位就记录为 1;如果是偶数个 1,那额外的一位就记录成 0。那额外的一位,我们就称之为校验码位

image-20240326184740368

如果在这个字节里面,我们不幸发生了单比特翻转,那么数据位计算得到的校验码,就和实际校验位里面的数据不一样。我们的内存就知道出错了。

除此之外,校验位有一个很大的优点,就是计算非常快,往往只需要遍历一遍需要校验的数据,通过一个 O(N) 的时间复杂度的算法,就能把校验结果计算出来。

不过,使用奇偶校验,还是有两个比较大的缺陷。

第一个缺陷,就是奇偶校验只能解决遇到单个位的错误,或者说奇数个位的错误。如果出现 2 个位进行了翻转,那么这个字节的校验位计算结果其实没有变,我们的校验位自然也就不能发现这个错误。

第二个缺陷,是它只能发现错误,但是不能纠正错误。所以,即使在内存里面发现数据错误了,我们也只能中止程序,而不能让程序继续正常地运行下去。

ECC内存

ECC 内存的全称是 Error-Correcting Code memory,中文名字叫作纠错内存。顾名思义,就是在内存里面出现错误的时候,能够自己纠正过来。

我们不仅能捕捉到错误,还要能够纠正发生的错误。这个策略,我们通常叫作纠错码(Error Correcting Code)又叫作纠删码(Erasure Code),不仅能够纠正错误,还能够在错误不能纠正的时候,直接把数据删除。

无论是我们的 ECC 内存,还是网络传输,乃至硬盘的 RAID,其实都利用了纠错码和纠删码的相关技术。

最知名的纠错码就是海明码。最基础的海明码叫7-4 海明码。这里的“7”指的是实际有效的数据,一共是 7 位(Bit)。而这里的“4”,指的是我们额外存储了 4 位数据,用来纠错。

纠错码的纠错能力是有限的。不是说不管错了多少位,我们都能给纠正过来。在 7-4 海明码里面,我们只能纠正某 1 位的错误。

4 位的校验码,一共可以表示 2^4 = 16 个不同的数。根据数据位计算出来的校验值,一定是确定的。所以,如果数据位出错了,计算出来的校验码,一定和确定的那个校验码不同。那可能的值,就是在 2^4 - 1 = 15 那剩下的 15 个可能的校验值当中。

15 个可能的校验值,其实可以对应 15 个可能出错的位。这个时候你可能就会问了,既然我们的数据位只有 7 位,那为什么我们要用 4 位的校验码呢?用 3 位不就够了吗?2^3 - 1 = 7,正好能够对上 7 个不同的数据位啊!

别忘了单比特翻转的错误,不仅可能出现在数据位,也有可能出现在校验位。校验位本身也是可能出错的。所以,7 位数据位和 3 位校验位,如果只有单比特出错,可能出错的位数就是 10 位,2^3 - 1 = 7 种情况是不能帮我们找到具体是哪一位出错的。

事实上,如果我们的数据位有 K 位,校验位有 N 位。那么我们需要满足下面这个不等式,才能确保我们能够对单比特翻转的数据纠错。这个不等式就是:
K + N + 1 < = 2 N K + N + 1 <= 2^N K+N+1<=2N
在有 7 位数据位,也就是 K=7 的情况下,N 的最小值就是 4。4 位校验位,其实最多可以支持到 11 位数据位。

image-20240326185140874

海明码的纠错原理

例如来算一个4-3 海明码(也就是 4 位数据位,3 位校验位)。

我们把 4 位数据位,分别记作 d1、d2、d3、d4。这里的 d,取的是数据位 data bits 的首字母。我们把 3 位校验位,分别记作 p1、p2、p3。这里的 p,取的是校验位 parity bits 的首字母。

从 4 位的数据位里面,我们拿走 1 位,然后计算出一个对应的校验位。这个校验位的计算用之前讲过的奇偶校验就可以了。

比如,我们用 d1、d2、d4 来计算出一个校验位 p1;用 d1、d3、d4 计算出一个校验位 p2;用 d2、d3、d4 计算出一个校验位 p3。就像下面这个对应的表格一样:

image-20240326185531119

这个时候如果 d1 这一位的数据出错了,会发生什么情况?

我们会发现,p1 和 p2 和校验的计算结果不一样。d2 出错了,是因为 p1 和 p3 的校验的计算结果不一样;d3 出错了,则是因为 p2 和 p3;如果 d4 出错了,则是 p1、p2、p3 都不一样。你会发现,当数据码出错的时候,至少会有 2 位校验码的计算是不一致的。

那我们倒过来,如果是 p1 的校验码出错了,会发生什么情况呢?这个时候,只有 p1 的校验结果出错。p2 和 p3 的出错的结果也是一样的,只有一个校验码的计算是不一致的。

所以校验码不一致,一共有 2^3-1=7 种情况,正好对应了 7 个不同的位数的错误。

image-20240326185557581

生成海明威码

比如说,我们这里的 7-4 海明码,就是一共 11 位。

然后,我们给这 11 位数据从左到右进行编号,并且也把它们的二进制表示写出来。

接着,我们先把这 11 个数据中的二进制的整数次幂找出来。在这个 7-4 海明码里面,就是 1、2、4、8。这些数,就是我们的校验码位,我们把他们记录做 p1~p4。如果从二进制的角度看,它们是这 11 个数当中,唯四的,在 4 个比特里面只有一个比特是 1 的数值。

那么剩下的 7 个数,就是我们 d1-d7 的数据码位了。

然后,对于我们的校验码位,我们还是用奇偶校验码。但是每一个校验码位,不是用所有的 7 位数据来计算校验码。而是 p1 用 3、5、7、9、11 来计算。也就是,在二进制表示下,从右往左数的第一位比特是 1 的情况下,用 p1 作为校验码。

剩下的 p2,我们用 3、6、10、11 来计算校验码,也就是在二进制表示下,从右往左数的第二位比特是 1 的情况下,用 p2。那么,p3 自然是从右往左数,第三位比特是 1 的情况下的数字校验码。而 p4 则是第四位比特是 1 的情况下的校验码。

image-20240326190150330

这个时候,任何一个数据码出错了,就至少会有对应的两个或者三个校验码对不上,这样我们就能反过来找到是哪一个数据码出错了。如果校验码出错了,那么只有校验码这一位对不上,我们就知道是这个校验码出错了。

海明距离

其实,我们还可以换一个角度来理解海明码的作用。

对于两个二进制表示的数据,他们之间有差异的位数,我们称之为海明距离。比如 1001 和 0001 的海明距离是 1,因为他们只有最左侧的第一位是不同的。而 1001 和 0000 的海明距离是 2,因为他们最左侧和最右侧有两位是不同的。

image-20240326190312200

所谓的进行一位纠错,也就是所有和我们要传输的数据的海明距离为 1 的数,都能被纠正回来。而任何两个实际我们想要传输的数据,海明距离都至少要是 3。你可能会问了,为什么不能是 2 呢?因为如果是 2 的话,那么就会有一个出错的数,到两个正确的数据的海明距离都是 1。当我们看到这个出错的数的时候,我们就不知道究竟应该纠正到那一个数了。

在没有纠错功能的情况下,我们看到的数据就好像是空间里面的一个一个点。这个时候,我们可以让数据之间的距离很紧凑,但是如果这些点的坐标稍稍有错,我们就可能搞错是哪一个点。

在有了 1 位纠错功能之后,就好像我们把一个点变成了以这个点为中心,半径为 1 的球。只要坐标在这个球的范围之内,我们都知道实际要的数据就是球心的坐标。而各个数据球不能距离太近,不同的数据球之间要有 3 个单位的距离。

image-20240326190417754

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1546250.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

放弃 Rust 选择 Zig,Xata 团队推出 pgzx —— 计划使用 Zig 开发基于 PG 的分布式数据库

Summary Xata 公司在基于 PostgresSQL 开发自己的分布式数据库&#xff0c;出于 Zig 和 C 语言以及 PostgreSQL 的 API 有更好的互操作性的考虑&#xff0c;他们选择了 Zig 而非当红炸子鸡语言 Rust。他们的博客文章中对 pgzx 进行了介绍。让我们来看下他们对 Zig 和 Rust 语言…

创建多节点 k8s 集群

主机IP系统master192.168.2.15ubuntu20.04 x64 2C 4GWorker1192.168.2.16ubuntu20.04 x64 2C 4GWorker1192.168.2.18ubuntu20.04 x64 2C 4G 使用 iterm2 连接四台服务器 command shift i 同时操作 初始化配置 关闭防火墙 systemctl stop firewalld systemctl disable firewa…

Qt篇——Qt无法翻译tr()里面的字符串

最近遇到使用Qt语言家翻译功能时&#xff0c;ui界面中的中文都能够翻译成英文&#xff0c;但是tr("测试")这种动态设置给控件的中文&#xff0c;无法翻译&#xff08;lang_English.ts文件中的翻译已经正确添加了tr()字符串的翻译&#xff09;。 上网搜了很多资料&am…

Redis(十八)Redlock算法

文章目录 自研锁逻辑lock加锁关键逻辑 Redlock红锁算法自研锁存在的问题Redlock算法设计理念RedisonRedisson使用案例Redisson源码分析多机案例 自研锁逻辑 按照JUC里面java.util.concurrent.locks.Lock接规范编写 lock加锁关键逻辑 加锁的Lua脚本&#xff0c;通过redis里面的…

vue3+vite - 报错 import.meta.glob() can only accept string literals.(详细解决方案)

报错说明 在vue3+vite项目中,解决报错: [plugin:vite:import-analysis] import.meta.glob() can only accept string literals. 如果我们报错差不多,就可以完美搞定这个错误。 解决教程 这个错误,是因为

【笔记】MJ Prompt

参数 --chaos 10 or --c 10, 0-10, defalut 0 --quality 1 or --q, 0.25-1, defalut 1 --iw 2, 0.5-2, --stylize 100 or --s 100, 0-1000, defalut 100 --cref URL --cw 100, 0-100stylize 风格化&#xff0c;MJ不同的出图模式&#xff0c;有默认的艺术风格&#xff0c;该值…

TCP协议中的传输控制机制图文详解「重传机制」「流量控制」「拥塞控制」

目录 TCP重传机制 超时重传 快速重传 SACK 方法 Duplicate SACK TCP 流量控制 滑动窗口 累积确认 窗口大小由哪一方决定&#xff1f; 接收窗口和发送窗口的大小是相等的吗&#xff1f; 流量控制 窗口关闭的后果 糊涂窗口综合症 TCP拥塞处理 为什么要有拥塞控制呀&#xff0c;不…

LinkedIn账号为什么被封?被封后如何解决?

近期会有一些小伙伴说自己遇到了帐号无法登录的情况&#xff0c;其实出现领英帐号被封号(被限制登录)主要会有两类情况&#xff0c;今天就给大家分享一下如果被封该如何解决&#xff0c;强烈建议收藏。 在电脑领英官网或者手机领英APP上&#xff0c;输入领英帐号密码点击登录后…

力扣● 84.柱状图中最大的矩形

84.柱状图中最大的矩形 需要找到元素i的上一个更小的元素leftmin和下一个更小的元素rightmin&#xff0c;这样leftmin和rightmin之间的元素都比当前元素i更大&#xff0c;那么矩形的宽就是中间的这些元素&#xff1a;可以从leftmin1延伸到rightmin-1&#xff0c;长即为height[i…

rancher2.6部署

rancher2.6部署 1、准备环境镜像 2、部署3、密码获取密码设置新密码 4、设置语言5、导入已有集群 1、准备 环境 docker-ce-20.10.23-3.el8.x86_64.rpm以及依赖rpm kubernetes&#xff1a;v1.23.17 镜像 &#xff08;rancher和k8s有个版本对应关系&#xff0c;rancher2.5就不…

走进redisson

这里作者将大家走进redisson&#xff0c;读完这篇相信加深你对redisson的获取锁&#xff0c;重入&#xff0c;超时&#xff0c;看门狗&#xff0c;发布订阅等原理和功能的理解。 本文将深入原理代码&#xff0c;给出每行代码的意义以及最后的效果&#xff0c;过程有些枯燥&…

Python 指南-最短路径(Dijkstra 算法):

Dijkstra 算法可在 Python 库 OSMNX 中实现&#xff0c;可用于查找两个位置之间按距离或时间加权的最短路径。该算法使用 OpenStreetMap (OSM) 网络来驾驶、步行或骑自行车&#xff0c;并在后台使用 Python 库 NETWORKX 查找路线。 编码练习 正如我提到的&#xff0c;我将做一…

MySQL数据库 @@transaction_isolation参数的查询及修改

在应用开发过程中&#xff0c;可能会检查mysql数据库初始化参数符合要求。 遇到这种情况就要进行相应的调整。 1、查询参数信息 select transaction_isolation; 2、找到配置文件 &#xff0c;以window系统为例。 修改前先关闭MySQL数据库服务 对应需要修改的参数&#xff…

C语言看完我这篇最详细文件操作,你不会也得会!!!

1.使用文件 我们写的程序的数据是存储在电脑内存中&#xff0c;如果程序退出&#xff0c;内存就会被回收&#xff0c;数据就丢失&#xff0c;内存更具有一些实时性&#xff0c;等再次运行程序的数据的&#xff0c;数据就消失了&#xff0c;如果想要持久化的保存&#xff0c;可以…

LangChain-Chatchat

文章目录 关于 LangChain-Chatchat特性说明实现原理文档处理流程技术路线图&#xff08;截止0.2.10&#xff09; 使用 关于 LangChain-Chatchat Langchain-Chatchat&#xff08;原Langchain-ChatGLM&#xff09;基于 Langchain 与 ChatGLM 等语言模型的本地知识库问答。 gith…

[自研开源] 数据集成之分批传输 v0.7

开源地址&#xff1a;gitee | github 详细介绍&#xff1a;MyData 基于 Web API 的数据集成平台 部署文档&#xff1a;用 Docker 部署 MyData 使用手册&#xff1a;MyData 使用手册 试用体验&#xff1a;https://demo.mydata.work 交流Q群&#xff1a;430089673 介绍 本篇基于…

STM32F4x7标准库移植LWIP

项目背景 使用GD芯片的我们&#xff0c;都会去参考ST的代码。可是呢&#xff0c;有一个很大的问题就是&#xff0c;ST早就提供HAL库了&#xff0c;而目前GD还只有标准库。在移植LWIP的时候&#xff0c;会有很多不便。 好在天无绝人之路&#xff0c;找到了一份ST的官方例程&am…

java常用IO流功能——字符流和缓冲流概述

前言&#xff1a; 整理下学习笔记&#xff0c;打好基础&#xff0c;daydayup! 之前说了下了IO流的概念&#xff0c;并整理了字节流&#xff0c;有需要的可以看这篇 java常用应用程序编程接口&#xff08;API&#xff09;——IO流概述及字节流的使用 字符流 FileReader(文件字…

基于注意力机制和损坏特征掩蔽的遮挡人脸识别

Occluded Face Recognition Based on Attention Mechanism and Damaged Feature Masking 摘要 本文提出了一种基于注意力机制&#xff08;BAM&#xff09;和掩模生成器的新型遮挡人脸识别方法。在主干网络中嵌入BAM以提取更多可区分的特征&#xff0c;同时设计掩模生成器来清理…