日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

嵌入式里如何给内存做压力测试?不妨试试memtester

發布時間:2023/12/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 嵌入式里如何给内存做压力测试?不妨试试memtester 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是內存讀寫正確性壓力測試程序memtester

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

一、內存性能測試程序集

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

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

二、memtester程序

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

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

2.1 獲取程序

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

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

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

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

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

2.2 配置參數

memtester源碼里的配置選項主要是如下五個宏:

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

2.3 程序解析

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

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");//?省略若干初始檢查代碼//?從輸入參數里獲取physaddrbase計算出內存測試起始地址aligned//?從輸入參數里獲取mem及B|K|M|G計算出內存測試總長度bufsizehalflen?=?bufsize?/?2;count?=?halflen?/?sizeof(ul);bufa?=?(ulv?*)?aligned;bufb?=?(ulv?*)?((size_t)?aligned?+?halflen);//?壓力測試的重要變量,?loops即重復次數for(loop=1;?((!loops)?||?loop?<=?loops);?loop++)?{printf("Loop?%lu",?loop);if?(loops)?{printf("/%lu",?loops);}printf(":\n");printf("??%-20s:?",?"Stuck?Address");fflush(stdout);//?第一個測試?stuck_addressif?(!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);//?可以看到將內存測試總空間一分為二,傳給子程序做處理的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個函數,涉及各種內存訪問經驗操作,具體可以看網上的一篇詳細解析文章 https://www.jianshu.com/p/ef203c360c4f。

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

2.4 結果格式

在Unix-like系統下使用make && make install命令進行編譯可得到一個可執行的memtester,可以隨便執行memtester 10M 1,即申請10M的內存測試1次,結果如下:

[root@as150 ~] memtester 10M 1memtester 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: okRandom Value: okCompare XOR: okCompare SUB: okCompare MUL: okCompare DIV: okCompare OR: okCompare AND: okSequential Increment: okSolid Bits: okBlock Sequential: okCheckerboard: okBit Spread: okBit Flip: okWalking Ones: okWalking Zeroes: ok8-bit Writes: ok16-bit Writes: okDone.

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


推薦閱讀:

專輯|Linux文章匯總

專輯|程序人生

專輯|C語言

我的知識小密圈

關注公眾號,后臺回復「1024」獲取學習資料網盤鏈接。

歡迎點贊,關注,轉發,在看,您的每一次鼓勵,我都將銘記于心~

總結

以上是生活随笔為你收集整理的嵌入式里如何给内存做压力测试?不妨试试memtester的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。