我们如何确保计算机永远不会意外地将0乘以1?


63

我已经在Shocken / Nisan的《计算系统的元素》中读过一些有关数字计算机构造的信息。但是这本书没有提到计算机中某些电气方面的信息,例如:经常说0和1由电压表示,如果电压在[0,0.9)区间内,则它是0。在区间[0.9,1.5)中,则为1(电压可能会有所不同,我仅举一个例子)。

但是我从来没有读过能使电压保持“良好状态”的方式,即由于计算机内部的电气波动[1],所以永远不会将0意外地变成1。也许电压可能非常接近0.9,那么如何避免电压超过阈值呢?

[1]:假设它存在。


7
电流永远不会非常接近0.9,因为没有任何东西能够使电流非常接近0.9。
immibis

7
因为东西被设计为不输出非常接近0.9的电流。您可能还会问:“我有确凿的经验证明,我的笔记本电脑未充电至50吉伏;为什么不呢?” 只是因为没有理由。
immibis '16

13
Nitpick:大多数数字逻辑使用电压而非电流来表示逻辑状态。
duskwuff '16

11
轶事证据:2011年,我在硬盘上交换了一个文件,该文件可以使用5年。
PlasmaHH 2016年

7
这些意外开关是可利用的。 Google的解释对此很有趣。当用于“将位X设置为1”的实际API为“将位X设置为1,有时不小心将位Y设置为1”时,这无疑会使安全性变得更加棘手。对于超频机器,这也变得非常普遍。我记得有一家公司实际上在已知结果的基础上添加了许多计算(每一帧),以查看硬件是否足够可靠以运行游戏。
布莱恩

Answers:


100

人们常说电压用0和1表示,如果电压在[0,0.9)区间内,则它是0。如果电压在[0.9,1.5)区间内,则它是1(电压可能会有所不同,我仅举一个例子)。

在某种程度上,您已经通过使用不切实际的示例来创建此问题。在实际电路中,逻辑低电平与高电平之间的差距要大得多。

例如,5V CMOS逻辑将为逻辑低输出0-0.2V,为逻辑高输出4.7-5V,并将始终接受1.3V以下的任何电压或3.7V以上的任何电压。也就是说,输出上的裕度比输入上的裕度小得多,并且可能用于逻辑低信号(<1.3V)的电压与可能用于逻辑高信号(> 3.7V)的电压之间还存在巨大的差距。 。所有这些都是专门设计的,以允许噪声,并防止您正在描述的那种意外切换。

这是我从interfacebus.com借用的各种逻辑标准的阈值的直观表示:

逻辑电平阈值] [1]

每一列代表一个逻辑标准,纵轴为电压。这是每种颜色代表的含义:

  • 橙色:此范围内的电压输出为逻辑高电平,并将被接受为逻辑高电平。
  • 浅绿色:此范围内的电压将被接受为逻辑高电平。
  • 粉色/蓝色:在此范围内的电压不会被一致地解释,但是粉红色区域中的电压通常最终会被解释为高电压,而蓝色区域中的电压通常会被低电压解释。
  • 蓝绿色:此范围内的电压将被接受为逻辑低。
  • 黄色:此范围内的电压输出为逻辑低,将被解释为逻辑低。

4
很好的答案,尽管我认为它可能更完整:您仅涵盖对噪声的免疫力(或更确切地说,针对噪声的防护)。还有许多其他机制负责数字错误,以及许多保护手段。好消息是,我的回答中并未涵盖抗干扰能力:)
迈斯特先生

1
@MisterMystère没错!但是,纠错是一个很大的话题,我不可能在一个答案中涵盖所有内容。
duskwuff '16

1
@MisterMystère:好吧,“噪声”是一个涵盖所有随机误差源的术语。您的EM干扰和宇宙辐射示例恰好属于“噪声”类别。数字错误的唯一其他原因是确定性原因,我们称其为“错误”。但是这个问题只是关于偶然的错误。
Ben Voigt

在您的第三个项目符号中,我相信您已经改变了颜色或逻辑。粉色应该低,蓝色应该高。
吉尔

@Guill Huh?粉色区域高于V_T,因此将其不可靠地视为逻辑高。
duskwuff '16

65

我们不能。我们只是通过向数据添加检查来减少错误的可能性。根据要检查的数据类型,可以通过硬件或软件来完成,并且可以采用任何形式,从串行流中的简单校验和位到循环状态机,仅允许在任何给定时间进行特定转换。

但这是一个恶性循环,不是吗?我们如何确保负责检查数据的电路不受与数据相同的干扰影响并给出假阳性?再添加一个?您会看到,最终它如何变得非常昂贵,却收效甚微。

问题是:您希望系统的可靠性如何?嵌入一​​些可用的最可靠的计算机系统的卫星,例如,有时会采用异类系统和选票的交叉冗余:三台不同的计算机以三种不同的方式运行由三个不同的人编码的相同算法,如果有的话的计算机给出的结果与其他两台计算机不同,它将重新启动(如果再次发生,则将其隔离)。但是同样,如果两台计算机同时出现故障,则错误的计算机将重新启动/隔离。通常,“冷冗余”就足够了:实现了主电路和辅助电路,主电路一直运行,直到某种(非保护性)监视电路检测到错误,然后将辅助电路交换了进来。在RAM中 可以重新运行代码以刷新数据。您只需要明智地决定在哪里画线,就不可能制造出100%可靠的错误检测电路。

由于高能粒子与半导体晶格碰撞或被半导体晶格吸收,卫星(尤其是在高空或范艾伦带上的卫星)和核电站或其他放射性环境中的计算机特别容易遭受(关键字:)单事件干扰或闩锁。涵盖这些领域的书籍无疑是您最好的选择。油漆会因辐射引起的位移破坏而退化,因此完全可以理解的是,半导体也可能受到入射辐射的破坏或破坏。


2
我不确定您是否打算写“恶性循环”,但“粘性循环”听起来同样很有趣。
svavil

1
其实这是一个可见的圈子,但粘性的圈子让我发笑了:)
先生

1
仅需要log n位就能找到并纠正n位中的单个位错误。
托尔比约恩Ravn的安徒生

1
这让我想起了最近的问题的有关编写程序在暴露于放射性化合物电脑占硬件错误:stackoverflow.com/questions/36827659/...
Pharap

我不了解卫星的事情,三个不同的“组”(或更多)正在以不同的方式编码同一件事。听起来很酷:)
kalmanIsAGameChanger

33

单项事件的烦恼不再是太空或飞机的事;我们已经看到它们在表面上发生了十多年,也许到现在已经发生了两个。

如前所述,至少在太空应用中,我们使用三重投票来解决问题(每个位实际上是三位,并且三分之二的选票获胜,因此,如果有更改,则另外两票可以解决)。然后是ECC或EDAC,其中洗涤器以高于预计的单个事件更新速率的速率通过RAM,以清除单个事件异常(实际上推动三分之二的表决错误)。

然后是总剂量;随着时间的流逝,这些材料会变得太放射性而无法工作,因此您要使用足够的材料来超过车辆的使用寿命。我们通常不会在表面上担心什么。(和闩锁)并行使用三组/多组逻辑是尝试不必使用传统的抗辐射技术的一种方法,而且,您可以找到有效的方法。

过去曾经知道如何为太空制造东西的人们大部分已经退休或继续工作,所以我们现在有许多程序可以浪费太空。或像对待地球上的产品一样对待太空,而不是试图使每个人都完成工作并进行可控制的重入和烧毁,我们现在期望每个星座中都有一定数量的太空垃圾。

我们确实在表面上看到不安。您购买的任何记忆棒(DRAM)均具有FIT,Failures In Time,并且其中具有RAM的任何芯片(所有处理器,还有许多其他处理器)也将具有FIT规范(用于RAM(SRAM)块)。RAM更加密集并且使用较小的晶体管,因此它更容易受到干扰,内部产生或外部破坏。在大多数情况下,我们不会注意到或关心用于数据,观看视频等的内存,这些内存在写入,读回并且在内存足够长的时间不会翻动之前就不再使用。某些内存(例如保存程序或内核的内存)的风险更大。但是长期以来,我们已经习惯了只重启计算机或重置/重启手机的想法(某些手机/品牌的手机必须定期定期取出电池)。是这些烦恼,不良软件还是两者的结合?

您单个产品的FIT编号可能会超过该产品的使用寿命,但是如果使用大型服务器场,则需要考虑所有RAM或芯片或其他因素,而MTBF则从数年或数月之久,到几天或几小时,甚至到农场。而且您有ECC可以解决这些问题。然后,您可以通过故障转移来分配处理负载,以覆盖未能完成任务的机器或软件。

对于固态存储的需求以及从旋转介质的转移已经引起了与此相关的问题。用于SSD的存储(以及其他非易失性存储)变得更快,更便宜,其易失性比我们想要的要大得多,并且依赖于EDAC,因为如果没有它,我们将丢失数据。他们投入了很多额外的钱,使整个事情都步履维艰,通过算术来平衡速度,成本和存储寿命。我看不到我们回头。人们到处都希望有更多的非易失性存储设备,这些存储设备必须装在一个很小的包装中,并且不能控制产品的价格。

就普通电路而言,从使用晶体管用于数字电路的初期到现在,我们通过晶体管的线性部分并将其用作开关,我们将其在导轨之间敲打,以确保其粘住。就像墙上的电灯开关一样,您将其翻转超过一半,弹簧可以帮助其余部分固定在那里。这就是为什么我们使用数字而不是尝试生活在线性区域的原因。他们尽早尝试,但失败了。他们无法保持校准状态。

因此,我们只是将晶体管猛拉到它的轨道中,信号的两侧将在下一个时钟周期之前稳定下来。在进行芯片设计分析时,要付出很大的努力,并且当前的工具要比以前的工具明显好得多,以确保通过设计在时序上有余地。然后在每个晶片上(在封装之后和/或在封装之后)测试每个管芯,以查看每个芯片是否良好。

芯片技术严重依赖基于实验的统计数据。当您超频CPU时,您会不断提高裕量,保持在标称的时钟频率,温度等之内,并且出现问题的机会大大降低。3 GHz xyz处理器只是4 GHz芯片,它在4 GHz时失败,但在3 GHz时通过。基本上从生产线对零件进行速度分级。

然后在芯片或电路板之间就存在连接,并且这些连接也容易出现问题,为减少这些接口的错误,在制定标准和电路板设计等方面花费了大量的时间和精力。 USB,键盘,鼠标,HDMISATA等。以及板上的所有走线。董事会内外都有串扰问题;同样,如果您使用它们,还有很多工具可以使用,并且从一开始就避免问题的经验,但是还有另一种方式,我们可能看不到零零零碎的东西。

哪怕是空间,都不是完美的技术。它仅需足够好,产品的足够百分比必须足以覆盖产品的预期寿命。一定比例的智能手机必须至少制造两年,仅此而已。较早的铸造厂或技术拥有更多的实验数据,可以生产出更可靠的产品,但速度较慢,并且可能不是新设计,因此您可以使用。最前沿的就是,对所有人来说都是一场赌博。

对于您的特定问题,信号两端的晶体管被​​快速推入它们的线性区域并倾斜到其中一个导轨中。对每条组合路径进行分析,以确定它会在路径末尾的时钟锁存之前稳定下来,从而使它真正为零或一。该分析基于实验。将产品线的第一批芯片推到设计界限之外,进行时序图确定设计中是否有余量。进行工艺上的变化和/或找到代表慢速和快速切屑的单个候选物。这是一个复杂的过程,有些材料更多,有些材料更少,运行速度更快,但使用更多的能量或运行速度更慢,等等。

您也将它们推到了边缘。基本上感觉到设计可以投入生产了。JTAG /边界扫描用于在每个锁存状态之间的芯片上运行随机模式,以查看组合路径对于设计而言都是可靠的。在有顾虑的地方,也可能会进行一些定向功能测试。对第一个硅片进行进一步测试,并可能进行随机测试以确保产品良好。如果/发生故障,则可能使您回到生产线上的更多功能测试。它在很大程度上取决于统计数据/百分比。1/1000000坏人出去可能没事,或者是1/1000或其他;这取决于您认为将生产该芯片的数量。

漏洞已在这里以及其他地方提到。首先,芯片本身,设计和工艺的质量如何,与保证金的接近程度是您购买产品中特定芯片的最薄弱环节。如果太靠近边缘,则温度变化或其他变化会引起时序问题,并且位将锁存尚未稳定为1或0的数据。然后是单个事件的问题。然后有噪音。再次提到的东西...


4
您的第一段听起来像航空航天环境不再存在任何问题,而我认为您的意思是SEU不再只是在这些环境中经历过。
W5VO

请注意,BEU上的SnPb焊料可能会导致SEU​​,这是因为除了自由中子活性之外,某些铅是铀衰变链的一部分。
彼得·史密斯

@ W5VO,是的,我的意思是,由于辐射引起的不适不再只是空间问题,而是一直到表面的问题。不如太空差,但存在。
old_timer '16

1
我似乎记得有些DEC小型计算机总线在实践中存在亚稳态问题。这是与您所命名的错误不同的机制,对吗?或不?
davidbak

2
@davidbak:亚稳态是一个令人讨厌的问题,其最常见的影响是,在最近的某个时候,某些位的值取决于某些输入是低电平还是高电平时,可能不会全部以与输入一致的方式一起切换为低,或以与高相同的方式,但可能会同时产生这两种行为。例如,如果应该在按下按钮时分支代码,则程序计数器位最终可能会保留它们在按下按钮或不按下按钮时所具有的值的任意混合。
超级猫

12

如果您只是一个简单的答案:

计算机产生的输出要比其接受的输入受更多限制。例如,任何从0V到2V的“输入”值都将被接受为0,但“输出” 0始终在0到0.5V范围内。(有关实际值,请参阅黄昏的答案。)

这意味着每个组件都有助于“校正”沿线发生的一些偏差或噪声。当然,如果噪声足够大,系统将无法补偿。高辐射环境中的计算机可能经常受到将1s更改为0s的影响,反之亦然。

基本上,计算机被设计为可以承受一定程度的噪声/干扰,对于大多数实际用途而言,这已经足够了。


8

理论上,由于热(和其他)噪声,信号可能会在0和1之间变化,但是这种可能性极小。

设计数字电路的属性称为“噪声余量”。这是输出翻转状态之前其输入必须更改的量。通常,在CMOS电路中,这约为电源电压的50%。这些电路中不可避免的热噪声(来自电子在高于0开尔文的温度下移动)产生了<< 1 mV的噪声,并且这些尖峰可能超过(例如)500 mV的可能性非常小。

数字(例如CMOS)门具有增益和饱和特性。这意味着,当输入信号接近范围的中间时,输出会快速变化(高增益),但是当接近范围的极限时,输出会缓慢变化。这样的结果是,当输入信号“接近”电源轨时,输出甚至更近-这意味着噪声不会被放大。

上面提到的其他功能(纠错等)意味着即使发生错误,错误也不会传播。


4

在容易出错的系统中,例如通信通道和磁性存储器(有时甚至是RAM),将存储校验和,CRC或ECC以拒绝不良数据或纠正小错误。

通常,二进制系统的设计是不可能的,但是一旦宇宙射线或一瞬间的噪声在几百万或十亿次中将在整个线上推动事物,就需要进行错误检测/纠正以保持损坏。不会严重影响计算机。

*通讯通道的错误率可能高得多!


4

计算机硬件变得更加强大和可靠。但是,对于一个简单的答案而言,硬件太广泛了。但是,可能有兴趣知道普通台式计算机和企业服务器计算机之间存在可靠性差异。我发现对服务器硬件的问题/答案线程。一台服务器的成本是同类台式机的许多倍。成本是由于硬件更好的结果,硬件可能意外“切换1和0”的几率要小几倍。

但是硬件只是故事的一半。计算机还可以使用软件保护数据免受意外错误的影响。汉明码是一个示例,其中通过添加少量附加数据,不仅可以检测到少量错误,而且可以纠正这些错误。


除了MLC闪存外,可靠性是以密度来
衡量的

3

2种被方式通常用来对一个逻辑位将是可能性最小化意外接通(0至1或1至0)。
第一是通过提供作为大的间隙,对a 0和a 1的定义的电压电平之间,尽可能。正如您提到的,0定义为<0.9v的电压电平,而1定义为> 2.9v的电压电平(不是您所说的0.9到1.5)。留下2v的电压间隙。这意味着在“意外”切换位状态之前(极不可能),信号电压将必须变化200%
第二种是通过“计时”逻辑信号。由于“偶然”电压/噪声是随机且短暂的,因此通过仅以特定(和较短)时间间隔进行状态更改,可使“变化”在时钟时间发生的可能性最小。

当然,根据所需的可靠性程度(ECD,ECC等),还有其他使用的手段和方法。


2

好的工程。

为了防止数据损坏或在无法充分防止数据损坏(例如ECC内存)时进行纠正, 设计人员付出了很多努力。

可能导致数据损坏的因素包括:

  • 电噪声环境
  • 电力相关问题
  • 时序问题(例如时钟线和数据线之间,或两条差分线之间)
  • 串扰

简而言之,许多工程已经进入数字设计,因此软件工程师可以简单地假设“ 0”表示“ 0”,“ 1”表示“ 1”。


当然,ECC内存还可以做一些有趣的事情,例如,如果损坏的位数多于可修复的位数,则触发不可屏蔽中断(NMI)。我认为对于现代ECC RAM,这是64位中的一个以上的位错误(编码可以纠正一位错误,并且可以检测但不能纠正两位错误),但是我对此可能是错误的。在您关心数据的情况下,如果有些东西无法修复,则立即停止系统可能比不知道是否可以信任数据(或者更糟糕的是,知道它不能信任)更容易。
CVn

2

实用电子计算机的两个基本方面是:

  1. 非常稳定的电源

  2. 时间(通常定义为时钟频率或延迟)

计算系统的电源非常严格地指定和调节。实际上,对于任何计算系统,电源通常都会进行多次调节:在电源(或电池充电器),在主板的主要输入,在子卡的输入以及最后在芯片本身上。

这样可以消除很多噪音(电气波动)。CPU看到的是一个非常稳定的非易失性电压源,可用于处理逻辑。

值转换时,出现下一个中间值的主要来源(介于0或1之间的电压)。1变为0(下降时间)或0变为1(上升时间)。除了等待转换完成再接受电路的输出之前,您实际上不能做太多事情。在转换完成之前,电路的输出被视为垃圾。

在工程设计中,解决此问题的方法是简单地在纸上写下等待结果正确的时间。这是CPU时钟频率的来源。CPU可以运行多少GHz取决于CPU状态变化稳定所需的时间。

实际上,还有第三种波动源:电路的输入。该问题的解决方案与上述一般问题类似:确保进入系统的信号(电压或电流)稳定,并确保信号有足够的时间稳定下来。

问题的第二部分是为什么我们在处理之前将输入采样到锁存器或寄存器中。该信号可能是垃圾。但是处理它们时,它们在寄存器内部将是0或1垃圾。问题的第一部分是保证的范围。


2

但是,我从来没有读过能使电压保持“良好状态”的方式,即由于计算机内部的电气波动1而导致0永远不会意外变为1 。也许电压可能非常接近0.9,那么如何避免电压超过阈值呢?

反馈阻止了它接近阈值电压,并迫使其表现良好。

这通常是某种形式的锁存电路的形式,通常是时钟锁存电路。

作为一个简单的示例,请考虑触发器。其设计目的是将输出作为附加输入反馈到逻辑电路中。因此,元素内的逻辑知道它正在输出什么,并且它将一直输出相同的值,直到其他输入迫使它进入相反的状态为止。

由于电路设计为晶体管处于完全导通或完全截止状态,因此它将始终在电源和接地极限附近输出-不会接近0.9v电平,并且在过渡时它将快速且完全移动到另一个状态。电路经过专门设计,以避免在两种状态之间的模拟区域中工作。


0

在正常工作条件下,0和1很少出现毛刺,但在恶劣的工作条件下(例如,电池电量低或交流电源断开且电容器中的电压下降后的短暂时间),会发生奇怪的事情,而0和1会混乱每时每刻。

因此,如果您要编写不想锁定的防御性代码(软件或HDL),则应始终考虑数字可能出现故障的情况。例如,

while(1)
{
  i++;
  do something here
  if (i == 10) break;
}

最好改变 ==>= 以防万一的值i从9到11或者任意数量大于10,这将导致你永远不会退出循环,直到跳i回到0(比如后4十亿次迭代)。

while(1)
{
  i++;
  do something here
  if (i >= 10) break;
}

发生了,相信我...


如果i跳到某个较大的负数怎么办?
杰森
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.