<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      痞子衡嵌入式:內(nèi)存讀寫正確性壓力測試程序(memtester)


        大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家介紹的是內(nèi)存讀寫正確性壓力測試程序memtester

        在嵌入式系統(tǒng)中,內(nèi)存(RAM)的重要性不言而喻,系統(tǒng)性能及穩(wěn)定性都與內(nèi)存息息相關(guān)。關(guān)于內(nèi)存性能有很多個(gè)不同指標(biāo),其中最基礎(chǔ)的指標(biāo)便是訪問可靠性(即讀寫的正確性),只有穩(wěn)定可靠的內(nèi)存訪問才能確保系統(tǒng)正常運(yùn)行。很多時(shí)候簡單地內(nèi)存讀寫測試并不能發(fā)現(xiàn)隱藏的問題,因此我們需要一個(gè)完備的內(nèi)存訪問壓力測試程序,今天痞子衡就和大家詳細(xì)聊一聊memtester。

      一、內(nèi)存性能測試程序集

        在講memtester之前,痞子衡先給大家科普一下Linux系統(tǒng)下常用的內(nèi)存性能測試工具,它們分別是mbw、memtester、lmbench、sysbench。這幾個(gè)測試工具(程序)各有側(cè)重點(diǎn):

      內(nèi)存帶寬測試工具            --mbw;
      內(nèi)存壓力測試工具            --memtester;
      內(nèi)存綜合性能測試工具        --lmbench;
      內(nèi)存申請與讀寫速度測試工具   --sysbench;
      

      二、memtester程序

        memtester是Simon Kirby在1999年編寫的測試程序(v1版),后來由Charles Cazabon一直維護(hù)更新(v2及之后版本),主要面向Unix-like系統(tǒng),官方主頁上介紹的是“A userspace utility for testing the memory subsystem for faults.”,其實(shí)就是為了測試內(nèi)存(主要DDR)的讀寫訪問可靠性(僅正確性,與速度性能無關(guān)),這是驗(yàn)證板級硬件設(shè)備必不可少的一項(xiàng)測試。

        整個(gè)memtester測試的視角就是從用戶的角度來看的,從用戶角度設(shè)立不同的測試場景即測試用例,然后針對性地進(jìn)行功能測試,注意是從系統(tǒng)級來測試,也就是說關(guān)注的不單單是內(nèi)存顆粒了,還有系統(tǒng)板級的連線、IO性能、PCB等等相關(guān)的因素,在這些因素的影響下,內(nèi)存是否還能正常工作。

      2.1 獲取程序

        memtester程序的最新版本是4.5.0,早期的v1/v2/v3版本目前下載不到了,2012年Charles Cazabon重寫了程序并發(fā)布了全新v4.0.0,此后一直不定期更新,v4.x也是當(dāng)前最流行的版本。

      核心程序下載: http://pyropus.ca/software/memtester/

        核心程序包下載后,在\memtester-4.5.0\下可找到源代碼。詳細(xì)源文件目錄如下:

      \memtester-4.5.0
                      \memtester.h
                      \memtester.c        --主程序入口
                      \sizes.h            --關(guān)于系統(tǒng)位數(shù)(32/64bit)的一些定義
                      \types.h            --所用數(shù)據(jù)類型的定義
                      \tests.h
                      \tests.c            --測試算法子程序
      

        如果是移植到ARM Cortex-M平臺下裸系統(tǒng)運(yùn)行,一般只需要簡單修改memtester.c文件即可,其他源文件就是一些頭文件包含方面的改動(dòng),memtester本身并沒有太多移植工作,其源碼本是用作在Unix-like系統(tǒng)上運(yùn)行的,而在嵌入式系統(tǒng)里運(yùn)行僅需要把一些跟系統(tǒng)平臺相關(guān)的代碼刪除即可,此外就是打印函數(shù)的實(shí)現(xiàn)。

      2.2 配置參數(shù)

        memtester源碼里的配置選項(xiàng)主要是如下五個(gè)宏:

      /* 如下需用戶自定義 */
      ULONG_MAX             -- 確定系統(tǒng)是32bit還是64bit
      TEST_NARROW_WRITES    -- 確定是否要包含8/16 bit寫測試
      
      /* 如下借助linux頭文件 */
      _SC_VERSION           -- posix system版本檢查
      _SC_PAGE_SIZE         -- 內(nèi)存page大小獲取
      MAP_LOCKED            -- Linux里mmap里的swap特性
      

      2.3 程序解析

        讓我們嘗試分析memtester主函數(shù)入口main,main()函數(shù)最開始都是一些輸入?yún)?shù)解析,其實(shí)主要就是為了獲取三個(gè)重要變量:內(nèi)存測試起始地址、內(nèi)存測試總長度、壓力測試循環(huán)次數(shù),有了這三個(gè)變量值之后便開始逐一跑tests.c文件里各項(xiàng)測試算法小函數(shù):

      struct test {
          char *name;
          int (*fp)();
      };
      
      struct test tests[] = {
          { "Random Value", test_random_value },
          { "Compare XOR", test_xor_comparison },
          { "Compare SUB", test_sub_comparison },
          { "Compare MUL", test_mul_comparison },
          { "Compare DIV",test_div_comparison },
          { "Compare OR", test_or_comparison },
          { "Compare AND", test_and_comparison },
          { "Sequential Increment", test_seqinc_comparison },
          { "Solid Bits", test_solidbits_comparison },
          { "Block Sequential", test_blockseq_comparison },
          { "Checkerboard", test_checkerboard_comparison },
          { "Bit Spread", test_bitspread_comparison },
          { "Bit Flip", test_bitflip_comparison },
          { "Walking Ones", test_walkbits1_comparison },
          { "Walking Zeroes", test_walkbits0_comparison },
      #ifdef TEST_NARROW_WRITES    
          { "8-bit Writes", test_8bit_wide_random },
          { "16-bit Writes", test_16bit_wide_random },
      #endif
          { NULL, NULL }
      };
      
      /* Function definitions */
      void usage(char *me) {
          fprintf(stderr, "\n"
                  "Usage: %s [-p physaddrbase [-d device]] <mem>[B|K|M|G] [loops]\n",
                  me);
          exit(EXIT_FAIL_NONSTARTER);
      }
      
      int main(int argc, char **argv) {
          ul loops, loop, i;
          size_t bufsize, halflen, count;
          void volatile *buf, *aligned;
          ulv *bufa, *bufb;
          ul testmask = 0;
      
          // 省略若干變量定義代碼
      
          printf("memtester version " __version__ " (%d-bit)\n", UL_LEN);
          printf("Copyright (C) 2001-2020 Charles Cazabon.\n");
          printf("Licensed under the GNU General Public License version 2 (only).\n");
          printf("\n");
      
          // 省略若干初始檢查代碼
          // 從輸入?yún)?shù)里獲取physaddrbase計(jì)算出內(nèi)存測試起始地址aligned
          // 從輸入?yún)?shù)里獲取mem及B|K|M|G計(jì)算出內(nèi)存測試總長度bufsize
      
          halflen = bufsize / 2;
          count = halflen / sizeof(ul);
          bufa = (ulv *) aligned;
          bufb = (ulv *) ((size_t) aligned + halflen);
      
          // 壓力測試的重要變量, loops即重復(fù)次數(shù)
          for(loop=1; ((!loops) || loop <= loops); loop++) {
              printf("Loop %lu", loop);
              if (loops) {
                  printf("/%lu", loops);
              }
              printf(":\n");
              printf("  %-20s: ", "Stuck Address");
              fflush(stdout);
      
              // 第一個(gè)測試 stuck_address
              if (!test_stuck_address(aligned, bufsize / sizeof(ul))) {
                   printf("ok\n");
              } else {
                  exit_code |= EXIT_FAIL_ADDRESSLINES;
              }
      
              // 遍歷tests.c里的所有測試子程序
              for (i=0;;i++) {
                  if (!tests[i].name) break;
                  if (testmask && (!((1 << i) & testmask))) {
                      continue;
                  }
                  printf("  %-20s: ", tests[i].name);
                  // 可以看到將內(nèi)存測試總空間一分為二,傳給子程序做處理的
                  if (!tests[i].fp(bufa, bufb, count)) {
                      printf("ok\n");
                  } else {
                      exit_code |= EXIT_FAIL_OTHERTEST;
                  }
                  fflush(stdout);
                  /* clear buffer */
                  memset((void *) buf, 255, wantbytes);
              }
              printf("\n");
              fflush(stdout);
          }
      }
      

        tests.c文件里才是最核心的壓力測試算法子程序,一共17個(gè)函數(shù),涉及各種內(nèi)存訪問經(jīng)驗(yàn)操作,具體可以看網(wǎng)上的一篇詳細(xì)解析文章 https://www.jianshu.com/p/ef203c360c4f。

      測試函數(shù)名 測試作用
      test_stuck_address 先全部把地址值交替取反放入對應(yīng)存儲位置,然后再讀出比較,重復(fù)n次
      test_random_value 等效test_random_comparison(bufa, bufb, count):數(shù)據(jù)敏感型測試用例
      test_xor_comparison 與test_random_value比多了個(gè)異或操作
      test_sub_comparison 與test_random_value比多了個(gè)減法操作
      test_mul_comparisone 與test_random_value比多了個(gè)乘法操作
      test_div_comparison 與test_random_value比多了個(gè)除法操作
      test_or_comparison 在test_random_comparison()里面合并了
      test_and_comparison 在test_random_comparison()里面合并了
      test_seqinc_comparison 是 test_blockseq_comparison的一個(gè)子集;模擬客戶壓力測試場景
      test_solidbits_comparison 固定全1后寫入兩個(gè)buffer,然后讀出比較,然后全0寫入讀出比較;這就是Zero-One算法
      test_blockseq_comparison 一次寫一個(gè)count大小的塊,寫的值是拿byte級的數(shù)填充32bit,然后取出對比,接著重復(fù)256次;也是壓力用例,只是次數(shù)變多了;
      test_checkerboard_comparison 把設(shè)定好的幾組Data BackGround,依次寫入,然后讀出比較
      test_bitspread_comparison 還是在32bit里面移動(dòng),只是這次移動(dòng)的不是單單的一個(gè)0或者1,而是兩個(gè)1,這兩個(gè)1之間隔著兩個(gè)空位/td>
      test_bitflip_comparison 也是32bit里面的一個(gè)bit=1不斷移動(dòng)生成data pattern然后,每個(gè)pattern均執(zhí)行
      test_walkbits1_comparison 與test_walkbits0_comparison同理
      test_walkbits0_comparison 就是bit=1的位置在32bit里面移動(dòng),每移動(dòng)一次就全部填滿buffer,先是從低位往高位移,再是從高位往低位移動(dòng)
      test_8bit_wide_random 以char指針存值,也就是每次存8bit,粒度更細(xì);
      test_16bit_wide_random 以unsigned short指針存值,也就是每次存16bit,不同粒度檢測;

      2.4 結(jié)果格式

        在Unix-like系統(tǒng)下使用make && make install命令進(jìn)行編譯可得到一個(gè)可執(zhí)行的memtester,可以隨便執(zhí)行memtester 10M 1,即申請10M的內(nèi)存測試1次,結(jié)果如下:

      [root@as150 ~] memtester 10M 1
      
      memtester version 4.5.0 (64-bit)
      Copyright (C) 2001-2020 Charles Cazabon.
      Licensed under the GNU General Public License version 2 (only).
      
      pagesize is 4096
      pagesizemask is 0xfffffffffffff000
      want 10MB (10485760 bytes)
      got  10MB (10485760 bytes), trying mlock ...locked.
      Loop 1/1:
        Stuck Address: ok
        Random Value: ok
        Compare XOR: ok
        Compare SUB: ok
        Compare MUL: ok
        Compare DIV: ok
        Compare OR: ok
        Compare AND: ok
        Sequential Increment: ok
        Solid Bits: ok
        Block Sequential: ok
        Checkerboard: ok
        Bit Spread: ok
        Bit Flip: ok
        Walking Ones: ok
        Walking Zeroes: ok
        8-bit Writes: ok
        16-bit Writes: ok
      
      Done.
      

        至此,內(nèi)存讀寫正確性壓力測試程序memtester痞子衡便介紹完畢了,掌聲在哪里~~~

      歡迎訂閱

      文章會(huì)同時(shí)發(fā)布到我的 博客園主頁CSDN主頁知乎主頁微信公眾號 平臺上。

      微信搜索"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機(jī)上第一時(shí)間看了哦。

      posted @ 2021-03-25 13:26  痞子衡  閱讀(6085)  評論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: www久久只有这里有精品| 内射视频福利在线观看| 日韩人妻无码一区二区三区99| 亚洲中文字幕有综合久久| 亚洲天堂一区二区三区四区| 中文字幕无码不卡免费视频| 人妻少妇精品系列| 亚洲精品专区永久免费区| 亚洲成人av在线资源| 中文字幕无码色综合网| 国产成人精品久久一区二区| 久久99日本免费国产精品| 亚洲av日韩av中文高清性色| 亚洲精品一区久久久久一品av | 精品国产中文字幕在线| 少妇裸交aa大片| 成人亚欧欧美激情在线观看| 国产一区二区三区18禁| 无套内谢少妇一二三四| 白嫩少妇无套内谢视频| 亚洲精品久久久久久久久久吃药| 欧美成人午夜性视频| 亚洲色一色噜一噜噜噜| 亚洲欧美国产免费综合视频| 亚洲狠狠狠一区二区三区| 亚洲精品一区二区口爆| 少妇精品导航| 国产午夜精品理论片久久影院 | 四虎网址| 国产免费性感美女被插视频| 老司机精品影院一区二区三区| 亚洲综合精品中文字幕| 国产精品一二三区蜜臀av| 美女黄网站人色视频免费国产| 99RE6在线观看国产精品| 亚洲综合一区二区三区不卡| 亚欧美闷骚院| 亚洲国产成人久久综合区| a级黑人大硬长爽猛出猛进| 祁连县| 日韩av日韩av在线|