有很多测试内存的软件。但是,许多测试只是将一些模式套用到内存上,而没有对内存体系结构或如何最好地检测错误进行深入思考或了解。这对于硬盘故障很有效,但很少发现间歇性错误。基于 BIOS 的内存测试对于查找间歇性内存错误毫无用处。
存储芯片由大量紧密堆积的存储单元组成,每位数据一个。绝大多数间歇性故障是这些存储单元之间相互作用的结果。通常,写入存储单元会导致相邻单元之一被写入相同的数据。有效的内存测试将尝试测试这种情况。因此,测试内存的理想策略如下:
- 用零写一个单元格
- 一次,一次或多次写入所有相邻的单元格
- 检查第一个单元格是否仍为零
很明显,这种策略需要对存储单元在芯片上的布局有确切的了解。另外,针对不同芯片类型和制造商的芯片布局的数量是无止境的,这使得该策略不切实际。但是,有些测试算法可以达到理想状态。
MemTest86测试算法
MemTest86使用两种算法,可以合理地近似上述理想的测试策略。这些策略中的第一个称为移动反演。移动反演测试的工作方式如下:
- 用模式填充内存
- 从最低地址开始
- 检查图案没有改变
- 写出图案补全
- 增加地址
- 重复
- 从最高地址开始
- 检查图案没有改变
- 写出图案补全
- 递减地址
- 重复
该算法非常适合理想的内存测试,但是存在一些限制。今天,大多数高密度芯片都存储4至16位宽的数据。对于超过一位宽的芯片,不可能仅选择性地读取或写入一位。这意味着我们不能保证已经测试了所有相邻单元格的相互作用。在这种情况下,我们能做的最好的事情就是使用一些模式来确保所有相邻单元至少已被写入所有可能的一和零组合。
还可以看到,缓存,缓冲和乱序执行将干扰移动反演算法,并降低效率。可以关闭高速缓存,但是不能禁用新的高性能芯片中的内存缓冲。为了解决这个限制,我创建了一种新的算法Modulo-X。此算法不受缓存或缓冲的影响。该算法的工作原理如下:
- 对于0-20的起始偏移量
- 每20个位置写一个图案
- 用模式补写其他所有位置
- 重复一次以上
- 每20个位置检查一次图案
该算法完成与移动反转几乎相同级别的邻接测试,但不受缓存或缓冲的影响。由于对所有内存执行了单独的写遍(1a,1b)和读遍(1c),因此我们可以确保所有缓冲区和缓存在遍之间都已刷新。选择20作为步幅大小有些随意。较大的步幅可能更有效,但执行时间会更长。选择20似乎是速度和彻底性之间的合理折衷。
个别测试说明
MemTest86执行一系列编号的测试部分以检查错误。这些测试部分包含测试算法,数据模式和缓存设置的组合。安排了这些测试的执行顺序,以便尽快发现错误。每个测试部分的说明如下:
测试0 [地址测试,步行测试,无缓存]
使用步进地址模式测试所有存储库中的所有地址位。
测试1 [地址测试,自己的地址,顺序]
每个地址都有自己的地址,然后检查一致性。从理论上讲,以前的测试应该可以解决所有内存问题。该测试应捕获以前未检测到的任何寻址错误。该测试是对每个可用CPU依次进行的。
测试2 [地址测试,自己的地址,并行]
与测试1相同,但测试使用所有CPU并使用重叠的地址并行完成。
测试3 [移动反演,一和零,并行
该测试使用具有全1和全0模式的移动反演算法。即使已在某种程度上影响测试算法,也会启用缓存。启用缓存后,此测试不会花费很长时间,并且应该很快找到所有“硬”错误以及一些更细微的错误。使用所有CPU并行执行此操作。
测试4 [移动反相,8位模式]
这与测试3相同,但是使用8位宽的“行走” 1和0模式。该测试将更好地检测“宽”存储芯片中的细微错误。
测试5 [移动反演,随机模式]
测试5使用与测试4相同的算法,但是数据模式是一个随机数并且是补码。该测试对于发现难以检测的数据敏感错误特别有效。每次通过的随机数顺序都不同,因此多次通过可提高有效性。
测试6 [整步,64步]
此测试通过使用块移动(movsl)指令对内存进行压力测试,该测试基于Robert Redelmeier的burnBX测试。使用每8个字节反转一次的移位模式来初始化内存。然后使用movsl指令移动4mb的内存块。移动完成后,将检查数据模式。由于仅在完成内存移动后才检查数据,因此无法知道错误发生在何处。报告的地址仅适用于发现错误模式的位置。由于移动被限制在一个8mb的内存段中,因此失败的地址将始终与所报告的地址相距小于8mb。此测试的错误不用于计算BadRAM模式。
测试7 [反向移动,32位模式]
这是移动反演算法的一种变体,该算法针对每个连续地址将数据模式左移一位。每次通过时,起始位位置向左移动。为了使用所有可能的数据模式,需要32次通过。该测试对于检测数据敏感错误非常有效,但是执行时间很长。
测试8 [随机数顺序]
该测试将一系列随机数写入内存。通过为随机数重置种子,可以创建相同的数字序列作为参考。首先检查初始模式,然后在下一个遍次进行补充和再次检查。但是,与移动反转不同,测试编写和检查只能在正向进行。
测试9 [模20,随机模式]
使用Modulo-X算法应该发现由于对算法的缓存和缓冲干扰而无法通过移动反转检测到的错误。
测试10 [位淡入测试,2种模式]
位淡入淡出测试会使用某种模式初始化所有内存,然后休眠几分钟。然后检查内存以查看是否有任何内存位已更改。使用全1和全零模式。
测试11 [随机数序列,64位]
该测试与测试8相同,但使用的是本机64位指令。
测试12 [随机数序列,128位]
该测试与测试8相同,但是使用了本机SIMD(128位)指令。
测试13 [锤测试]
行锤测试暴露出DDR3、DDR4或更高版本的根本缺陷。当在短时间内重复访问同一存储体但不同行中的地址时,此缺陷可能导致干扰错误。行的重复打开/关闭会导致相邻行中的电荷泄漏,从而可能导致位翻转。
该测试通过交替读取两个地址来“锤击”行,然后验证其他地址的内容是否存在干扰错误。有关DRAM干扰错误的更多详细信息,请参见Yoongu Kim等人的“不访问就翻转内存中的位:DRAM干扰错误的实验研究”。
从MemTest86 v6.2开始,可能会两次通过行锤测试。在第一遍中,地址对以最高可能的速率被锤击。如果在第一次通过时检测到错误,则不会立即报告错误,而是开始第二次通过。在此过程中,地址对被内存供应商认为是最坏情况的速率降低(每64ms 200K次访问)。如果在此过程中还检测到错误,则将错误照常报告给用户。但是,如果仅第一遍产生错误,则会向用户显示警告消息。
MemTest86在我的内存中检测到错误。我的RAM出问题了吗?
请注意,并非MemTest86报告的所有错误均归因于内存故障。该测试隐含测试CPU,L1和L2缓存以及主板。测试无法确定导致故障发生的原因。但是,大多数故障将归咎于内存模块的问题。如果不是这样,唯一的选择就是更换零件,直到解除故障为止。
有时由于硬件不兼容而出现内存错误。内存模块在一个平台上可以正常工作,而在另一个平台上则不能正常工作。这并不少见,并且引起混乱。在这些情况下,这些硬件不一定是坏的,但有一些特定条件,当与其他组件结合使用时会导致错误。
内存通常在不同的系统中工作,或者供应商坚持认为它是好的。在这些情况下,内存不一定坏,但不能全速可靠地运行。有时主板上更保守的内存时序将纠正这些错误。在其他情况下,唯一的选择是用质量更好,速度更快的内存替换。不要购买便宜的内存并期望它能够可靠地工作。有时,即使使用名牌内存和优质主板,也会出现“块移动”测试错误。
所有显而易见的内存错误都应得到纠正。在正常操作中可能永远不会出现特定的错误。但是,使用故障内存有风险,并且可能导致数据丢失甚至磁盘损坏。即使没有明显的问题迹象,您也不能认为系统不受影响。有时,间歇性错误可能会导致长时间不明显的问题。
经常有人问我们MemTest86报告的错误的可靠性。在大多数情况下,测试报告的错误是有效的。有一些硬件环境使MemTest86在内存大小上感到困惑,并且它将尝试测试不存在的内存地址。这将导致大量连续地址被报告为错误,并且通常会有很多错误位。如果您的失败地址数量相对较少,并且只有一位或两位错误,则可以确定错误是有效的。间歇性错误同样无一例外地有效。内存供应商经常质疑MemTest86是否支持其特定的内存类型或芯片组。MemTest86旨在与所有内存类型和所有芯片组一起使用。
MemTest86无法诊断许多类型的PC故障。例如,导致Windows崩溃的故障CPU很可能仅以相同的方式导致MemTest86崩溃。
为什么在Test 13 Hammer Test期间我只会出现错误?
锤击测试旨在检测易受电荷泄漏引起的干扰错误影响的RAM模块。此现象在研究论文中指出:不访问就翻转内存中的位:DRAM干扰错误的实验研究Yoongu Kim等人。根据研究,此缺陷会影响2010年或以后生产的大量RAM模块。简而言之,当在短时间内重复访问同一存储体但不同行中的地址时,易受影响的RAM模块可能会遭受干扰错误。当重复访问导致存储单元中的电荷丢失时,会在下一个DRAM刷新间隔刷新单元内容之前发生错误。
从MemTest86 v6.2开始,用户可能会看到一条警告,指示“RAM may be vulnerable to high frequency row hammer bit flips”。当在第一遍(最大锤击率)期间检测到错误,但在第二遍(较低锤击率)期间未检测到错误时,将出现此警告。请参阅前文详细介绍了锤测试(测试13)中执行的两次通过。执行第二遍时,仅以内存供应商认为的最大速率(每64ms 200K次访问)锤打地址对。一旦超过此速率,就可能不再保证存储器内容的完整性。如果两次均检测到错误,则将错误报告为正常。
尽管仅在极端的内存访问情况下暴露,但在测试13中检测到的错误是最肯定的错误。在典型的家用PC使用期间(例如,Web浏览,文字处理等),内存使用模式不太可能陷入极端情况。如果您正在运行高度敏感的设备(例如医疗设备,飞机控制系统或银行数据库服务器),则会让人引发担忧。这些误差在现实生活中是否会发生,是不可能准确预测的。一个人需要对1000台计算机及其使用模式进行重大科学研究,然后对每个应用程序进行取证分析,以研究其在执行过程中如何利用RAM。迄今为止,由于执行锤击测试,我们仅看到1位错误。
当发现RAM模块容易受到干扰错误的影响时,可以采取几种措施:
- 什么也不做
- 更换内存
- 使用具有错误检查功能的内存(例如ECC)
根据您愿意忍受这些错误表现为实际问题的可能性,您可以选择不采取任何措施并承担风险。对于家庭使用,您可能愿意忍受这些错误。根据我们的经验,尽管有锤测试中的错误,我们还是有几台稳定的家用/办公用机器。
您也可以选择将RAM替换为已知通过锤测试的模块。选择不同品牌/型号的RAM模块,因为相同型号的RAM模块很可能仍无法通过Hammer测试。
对于要求高可用性/可靠性的敏感设备,您可以毫无疑问地更换RAM,并可能使用纠错功能切换到RAM,例如ECC RAM。即使是1位错误也可能导致灾难性的后果,例如银行帐户余额。请注意,并非所有主板都支持ECC内存,因此在购买ECC RAM之前,请查阅主板规格。
为什么仅在一起测试RAM模块时而不是单独测试时才出现错误?
如今,大多数内存系统都以多通道模式运行,以提高RAM模块与内存控制器之间的传输速率。在多通道模式下运行时,建议使用规格相同的模块(即“匹配模块”)。在多通道模式下运行时,某些主板还与某些品牌/型号的RAM存在兼容性问题。
当您在运行安装了多个RAM模块的MemTest86时看到错误,但是当单独测试它们时却没有,则可能是多通道配置的罪魁祸首。这可能是由于RAM规格不匹配,或者仅仅是使用了与主板不兼容的RAM品牌/型号。大多数主板供应商都会发布已知的兼容RAM型号列表,这些型号已经过测试,可以与您的主板一起使用。用一组匹配的已知良好模块替换模块,然后查看是否可获得更好的效果。
MemTest86报告了失败的内存地址。这是什么意思?
当MemTest86在内存测试期间检测到错误时,会将内存地址,实际和预期数据报告给用户。内存地址是系统内存中包含的数据与预期的不匹配的位置。当从DRAM请求数据时,这是CPU为存储控制器指定的地址。然后,存储器控制器使用芯片组特定的地址解码方案对该存储器地址进行解码,以识别DRAM中的特定通道,DIMM,等级,DRAM芯片,存储体,行和列。
地址解码方案是存储控制器用来生成适当地址信号到DRAM芯片的过程。根据存储控制器的不同,此过程可能会变得相当复杂,因为它不仅是系统地址位到DRAM地址位的直接映射。为了提高内存性能,使用了一些策略,例如通道交错(用于双通道,三通道和四通道设置),等级/库/行交错和地址刷新,以增加内存访问的并发性。对于某些芯片组(例如AMD),如芯片组规范中所述,可以通过PCI寄存器配置/确定地址解码方案。但是,对于其他芯片组(例如Intel),地址解码方案是专有的,并且不公开。这使得识别内存地址以及相应的故障模块变得更加困难。
MemTest86如何报告ECC错误?
如果系统上启用了ECC检测和纠正,则MemTest86能够将检测到的所有ECC错误报告给用户。根据所使用的芯片组,报告的ECC错误地址可以是系统内存地址(例如0x93801200)或DRAM列/组/行/列地址(例如0x3E0、0x5F6D,0x2、0x2)。这完全取决于所使用的芯片组以及硬件如何向系统报告ECC错误详细信息。就是 MemTest86不具有在显示系统地址或DRAM地址之间互换的功能。
如何解决内存错误?
根据导致内存错误的原因,可以尝试以下选项:
- 更换内存(最常见的解决方案)
- 设置默认或保守的内存时序
- 增加内存电压
- 更新BIOS以解决不兼容问题
- 将地址范围标记为“坏块”
有时,只有在BIOS中将RAM时序设置得过大时(例如超频),才会出现内存错误。对于某些支持更高性能XMP时序的模块,请考虑使用标准的非XMP时序,以查看是否获得更好的结果。请查阅主板手册,以了解如何将RAM时序设置或重置为默认设置。
对于某些配置(尤其是在使用主动RAM时序时),可能需要更高的电压才能在稳定条件下运行RAM。如果您使用非标准的RAM时序,则稍微增加电压(例如,从1.25V到1.35V)可能会增加稳定性。升高电压需要您自担风险,因为过高的电压可能会损坏内存
在某些情况下,BIOS更新可以解决RAM不兼容的问题。请检查主板供应商,以获取具有RAM兼容性修补程序的更新BIOS。
几个操作系统允许用户传递“坏”内存范围的列表,以防止操作系统使用或分配该范围内的内存。对于使用BadRAM支持进行编译的Linux内核,可以将BadRAM模式作为引导时间参数传入。这种变通办法使Linux可以在有缺陷的RAM的情况下可靠地运行。有关Linux对BadRAM支持的更多信息,请参见以下页面:http ://home.zonnet.nl/vanrein/badram
在Windows下,可以通过BCD系统存储传递已知的“不良”内存范围列表。有关管理不良内存页面列表的详细信息,请参见以下页面:http : //superuser.com/questions/420051/running-windows-with-defective-ram