Redis源代码分析(十一年)--- memtest内存测试

时间:2021-08-29 12:40:15

今天,我们继续redis源代码test下测试在封装中的其它文件。今天读数memtest档,翻译了,那是,memory test 存储器测试工具。。可是里面的提及了非常多东西,也给我涨了非常多见识,网上关于memtest这样的类似的redis内部边缘的文件解析基本没有,所以自己从头開始学习。机器的内存检測会和机器的CPU位数有关,32位或64位会影响后面的一些宏定义參数。

首先亮出memtest中的API:

/* 内存检測API */
void memtest_progress_start(char *title, int pass) /* 内存检測载入開始,输出開始的一些图线显示 */
void memtest_progress_end(void) /* progress bar载入完再次清屏操作 */
void memtest_progress_step(size_t curr, size_t size, char c) /* progress填充自己设置的字符串 */
void memtest_addressing(unsigned long *l, size_t bytes) /* 地址检測方法 */
void memtest_fill_random(unsigned long *l, size_t bytes) /* 随机填充内存 */
void memtest_fill_value(unsigned long *l, size_t bytes, unsigned long v1, unsigned long v2, char sym) /* 像上面的方法,仅仅只是这是特定2种值的填充v1,v2 */
void memtest_compare(unsigned long *l, size_t bytes) /* 内存比較方法 */
void memtest_compare_times(unsigned long *m, size_t bytes, int pass, int times) /* 进行多次内存compare比較操作 */
void memtest_test(size_t megabytes, int passes) /* 整个内存检測类操作的測试方法,passes为目标的循环数 */
void memtest_non_destructive_invert(void *addr, size_t size) /* 将内存地址,进行了按位取反操作。不具有对数据的破坏性 */
void memtest_non_destructive_swap(void *addr, size_t size) /* 将内存地址,2个,2个内部之间做交换,相同不正确数据具有破坏性 */
void memtest(size_t megabytes, int passes) /* 开发给整个系统使用的内存检測方法 */

里面基本的方法就几个,每当一个内存检測的開始,都会出现progress bar的图线输出:

/* 内存检測载入開始,输出開始的一些图线显示 */
void memtest_progress_start(char *title, int pass) {
int j; /*这里事实上包括2个命令。"\xlb[H","xlb[2j",后面的命令是基本的操作
*"\x1b" 是ESC的16进制ASCII码值,这里也可经表示成八进制的\033,
*[是一个CSI(Control sequence introducer),转义序列的作用由最后一个字符决定的,
*这里J表示删除,默认情况下它删除从当前光标处到行尾的内容,
*这里的2为參数,它表示删除全部的显示内容。 也能够使用printf "\x1b[2J"。*/
//现定位home最開始的位置。然后实现请屏幕操作
printf("\x1b[H\x1b[2J"); /* Cursor home, clear screen. */ /* Fill with dots. */
/* 输出.符号填充屏幕 */
for (j = 0; j < ws.ws_col*(ws.ws_row-2); j++) printf(".");
printf("Please keep the test running several minutes per GB of memory.\n");
printf("Also check http://www.memtest86.com/ and http://pyropus.ca/software/memtester/");
//最后一个參数变了,为K,意义也不一样了变成删除当前行操作
printf("\x1b[H\x1b[2K"); /* Cursor home, clear current line. */
printf("%s [%d]\n", title, pass); /* Print title. */
progress_printed = 0;
//求出填满progress bar所需点的个数
progress_full = ws.ws_col*(ws.ws_row-3);
fflush(stdout);
}

我在里面解释了一下清屏操作的。printf输出形式。

内存地址有效性的核心方法;

/* Test that addressing is fine. Every location is populated with its own
* address, and finally verified. This test is very fast but may detect
* ASAP big issues with the memory subsystem. */
/* 此方法是測试内存地址是否有效。此种检測的速度是很快的。但可能会检測出ASAP的巨大问题 */
/* ASAP网上查了下:(可能为)Automated Statistical Analysis Programme 自己主动统计分析程序 */
void memtest_addressing(unsigned long *l, size_t bytes) {
//算出地址的长度
unsigned long words = bytes/sizeof(unsigned long);
unsigned long j, *p; /* Fill */
p = l;
for (j = 0; j < words; j++) {
//将(unsigned long)p强制类型转换到此时的*p,后面以此来推断,没有转换成功,说明存在内存地址的问题
*p = (unsigned long)p;
p++;
//用A字符填充部分progress bar
if ((j & 0xffff) == 0) memtest_progress_step(j,words*2,'A');
}
/* Test */
p = l;
for (j = 0; j < words; j++) {
//比較Address的关键在于
if (*p != (unsigned long)p) {
printf("\n*** MEMORY ADDRESSING ERROR: %p contains %lu\n",
(void*) p, *p);
exit(1);
}
p++;
if ((j & 0xffff) == 0) memtest_progress_step(j+words,words*2,'A');
}
}

为什么这个方案去检測。本人也是带着比較疑惑的感觉。在内存检測中,内存地址有效性的检查仅仅是当中的一个方法。另一个是内存地址的填充測试,分为随机填充。和给定值的填充。以下给出随机填充的方法实现:

/* Fill words stepping a single page at every write, so we continue to
* touch all the pages in the smallest amount of time reducing the
* effectiveness of caches, and making it hard for the OS to transfer
* pages on the swap. */
/* 在每次写操作的时候,在单页上填满整个字符,这样能够做到最高速的触及全部的页面 */
/* 降低了低效率的缓存使用,可是会让分区在转移页面时会比較困难 */
/* 随机填充内存 */
void memtest_fill_random(unsigned long *l, size_t bytes) {
unsigned long step = 4096/sizeof(unsigned long);
unsigned long words = bytes/sizeof(unsigned long)/2;
unsigned long iwords = words/step; /* words per iteration */
unsigned long off, w, *l1, *l2; assert((bytes & 4095) == 0);
for (off = 0; off < step; off++) {
l1 = l+off;
l2 = l1+words;
for (w = 0; w < iwords; w++) {
//以下的rand()达到了随机存储的目的
#ifdef MEMTEST_32BIT
*l1 = *l2 = ((unsigned long) (rand()&0xffff)) |
(((unsigned long) (rand()&0xffff)) << 16);
#else
*l1 = *l2 = ((unsigned long) (rand()&0xffff)) |
(((unsigned long) (rand()&0xffff)) << 16) |
(((unsigned long) (rand()&0xffff)) << 32) |
(((unsigned long) (rand()&0xffff)) << 48);
#endif
l1 += step;
l2 += step;
if ((w & 0xffff) == 0)
memtest_progress_step(w+iwords*off,words,'R');
}
}
}

填充内存的优点是訪问页面速度更快,不会出现断断续续的内存片。可是做页面交换的时候。因为没有空间,效率恐怕会比較低下。给定数值的填充与上面的类似,不展开说了。那么,内存測试程序究竟是測哪些东西的呢,也就是说,他这个文件开放给外部的一个最直接的test方法是什么呢?

/* 整个内存检測类操作的測试方法,passes为目标的循环数 */
void memtest_test(size_t megabytes, int passes) {
size_t bytes = megabytes*1024*1024;
unsigned long *m = malloc(bytes);
int pass = 0; if (m == NULL) {
fprintf(stderr,"Unable to allocate %zu megabytes: %s",
megabytes, strerror(errno));
exit(1);
} //必须经过passes论循环測试
while (pass != passes) {
pass++; //地址检測
memtest_progress_start("Addressing test",pass);
memtest_addressing(m,bytes);
memtest_progress_end(); //随机填充检測
memtest_progress_start("Random fill",pass);
memtest_fill_random(m,bytes);
memtest_progress_end();
//填充后比較四次
memtest_compare_times(m,bytes,pass,4); //给定数值填充,这里称为Solid fill固态填充
memtest_progress_start("Solid fill",pass);
memtest_fill_value(m,bytes,0,(unsigned long)-1,'S');
memtest_progress_end();
//填充后比較四次
memtest_compare_times(m,bytes,pass,4); //也是属于给定数值填充,这里叫Checkerboard fill键盘填充
memtest_progress_start("Checkerboard fill",pass);
memtest_fill_value(m,bytes,ULONG_ONEZERO,ULONG_ZEROONE,'C');
memtest_progress_end();
//填充后比較四次
memtest_compare_times(m,bytes,pass,4);
}
free(m);
}

能够看见,分为4中情况,1内存地址測试,2,3,4都为填充測试,分为3种类型的填充Random fill, Solid fill, Checkboard fill 。填充之后再做内存比較,这里的内存比較是在内存内部做前半部分的内存和后半部分的内存比較操作。在memtest文件的最后。提到了一个这个方案:

/* 开发给整个系统使用的内存检測方法 */
void memtest(size_t megabytes, int passes) {
if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
ws.ws_col = 80;
ws.ws_row = 20;
}
memtest_test(megabytes,passes);
printf("\nYour memory passed this test.\n");
printf("Please if you are still in doubt use the following two tools:\n");
printf("1) memtest86: http://www.memtest86.com/\n");
printf("2) memtester: http://pyropus.ca/software/memtester/\n");
exit(0);
}

这里提到了memtester和memtest86,上网查了一下,大体例如以下:

* * memtest和memtest86是2款内存检測软件 

 * memtest不但能够彻底的检測出内存的稳定度,还可同一时候測试记忆的储存与检索数据的能力,让你能够确实掌控到眼下你机器上正在使用的内存究竟可不可信赖。 

 * MemTest是一个绿色软件。直接点击执行文件就可以执行 

 * memtest86这是一款小巧而专业的内存測试程序,是在著名的内存測试软件Memtest86基础上开发的。 

 * Memtest86+的安装和使用和其他内存測试软件有些不同,由于他不能在Windows下执行。

* 只是还是有四种方式能够执行此程序,分别为ISO引导盘、Linux下使用的bin文件、

 * USB启动盘使用的EXE文件和软盘引导制作包。

因为Memtest86+測试耗时较长,因此它不仅能够用于内存測试,还能够用于系统稳定性測试。Memtest86+測试完成后,

 * 按“Esc”退出并重新启动系统。

版权声明:本文博主原创文章。博客,未经同意不得转载。

Redis源代码分析(十一年)--- memtest内存测试的更多相关文章

  1. redis 源代码分析&lpar;一&rpar; 内存管理

    一,redis内存管理介绍 redis是一个基于内存的key-value的数据库,其内存管理是很重要的,为了屏蔽不同平台之间的差异,以及统计内存占用量等,redis对内存分配函数进行了一层封装,程序中 ...

  2. Redis源代码分析(一)--Redis结构解析

    从今天起,本人将会展开对Redis源代码的学习,Redis的代码规模比較小,很适合学习,是一份很不错的学习资料,数了一下大概100个文件左右的样子,用的是C语言写的.希望终于能把他啃完吧,C语言好久不 ...

  3. Redis源代码分析(23)--- CRC循环冗余算法RAND随机数的算法

    他今天就开始学习Redis源代码的一些工具来实现,在任何一种语言工具.算法实现的原理应该是相同的,一些比較经典的算法.比方说我今天看的Crc循环冗余校验算法和rand随机数产生算法. CRC算法全称循 ...

  4. Redis源代码分析(十)--- testhelp&period;h小测试框架和redis-check-aof&period;c 日志检测

    周期分析struct结构体redis代码.最后,越多越发现很多的代码其实大同小异.于struct有袋1,2不分析文件,关于set集合的一些东西,就放在下次分析好了,在选择下个分析的对象时,我考虑了一下 ...

  5. Redis源代码分析-内存数据结构intset

    这次研究了一下intset.研究的过程中,一度看不下过去,可是还是咬牙挺过来了.看懂了也就是那么回事.静下心来,切莫浮躁 Redis为了追求高效,在存储下做了非常多的优化,像intset就是作者为了节 ...

  6. Redis源代码分析(三十五)--- redis&period;c服务端的实现分析(2)

    在Redis服务端的代码量真的是比較大,假设一个一个API的学习怎么实现,无疑是一种效率非常低的做法,所以我今天对服务端的实现代码的学习,重在他的运行流程上.而对于他的模块设计在上一篇中我已经分析过了 ...

  7. Redis源代码分析(六)--- ziplist压缩列表

    ziplist和之前我解析过的adlist列表名字看上去的非常像.可是作用却全然不同.之前的adlist主要针对的是普通的数据链表操作. 而今天的ziplist指的是压缩链表.为什么叫压缩链表呢.由于 ...

  8. Redis源代码分析(三)---dict哈希结构

    昨天分析完adlist的Redis代码.今天立即马不停蹄的继续学习Redis代码中的哈希部分的结构学习,只是在这里他不叫什么hashMap,而是叫dict.并且是一种全新设计的一种哈希结构,他仅仅是通 ...

  9. Redis源代码分析(二十八)--- object创建和释放redisObject物

    今天的学习更有效率.该Rio分析过,学习之间的另一种方式RedisObject文件,只想说RedisObject有些生成和转换.都是很类似的.列出里面长长的API列表: /* ------------ ...

随机推荐

  1. CP

    cp:copy files and directories,如果要拷贝目录,则使用-a或者-r参数,则能够拷贝目录, 如果源文件是多个,那目标文件在最后,且是目录. Cp [-aifpru] [源文件 ...

  2. Andorid项目创建AVD时,OK按钮无法点亮

    经上网查证,发现原因在于CPU/ABI选项无法选择,并显示“No system images installed for this target”,也就是没有适合的系统镜像,通过与安装好了的ADT-b ...

  3. pwnable&period;kr-random

    题目 首先我们要对rand&srand有个总体的看法:srand初始化随机种子,rand产生随机数,下面将详细说明. rand(产生随机数) 表头文件: #include 定义函数 :int ...

  4. JVM 内存的那些事

    转自:http://blog.jobbole.com/104863/ 对于Java程序员你来说,在虚拟机内存管理的帮助下,不需要为每个new对象都匹配free操作,内存泄露和内存溢出等问题也不太容易出 ...

  5. URAL 1346&period; Intervals of Monotonicity&lpar;DP&rpar;

    题目链接 错误的贪了一下,然后D了两下就过了.注意是不上升和不下降..不是上升和下降.. #include <cstring> #include <cstdio> #inclu ...

  6. &commat;valid表单验证demo

    springMVC 表单验证demo  视图层使用的是jsp

  7. linux signal 用法和注意事项

    http://blog.chinaunix.net/uid-9354-id-2425031.html 所以希望能用相同方式处理信号的多次出现,最好用sigaction.信号只出现并处理一次,可以用si ...

  8. Regular expression cheat sheet

    \s white-space characters \S Non-white-space characters \d digital numbers \D non-digital numbers \w ...

  9. 控制反转IOC与依赖注入DI【转】

    转自:http://my.oschina.net/1pei/blog/492601 一直对控制反转.依赖注入不太明白,看到这篇文章感觉有点懂了,介绍的很详细. 1. IoC理论的背景我们都知道,在采用 ...

  10. flash跨域策略文件crossdomain&period;xml

    flash在跨域时唯一的限制策略就是crossdomain.xml文件,该文件限制了flash是否可以跨域读写数据以及允许从什么地方跨域读写数据. 位于www.a.com域中的SWF文件要访问www. ...