memsetとbzeroの効率テスト.


従来,mesetとbzeroの効率問題は,小オブジェクトを初期化する際にmemsetよりもbzeroの方が効率的であると考えられる.今日テストプログラムを書きました.以下のようにします.
このテストコードは,それぞれ4バイト整数,11バイトの配列,8192バイトの配列を初期化し,100000回実行し,平均値を求める.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

static inline unsigned long long rdtsc(void)
{
    unsigned hi, lo;
    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
    return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}

int main()
{

    unsigned long long start , end;
    unsigned long long diff;
    unsigned long long memset_avg_diff1 , memset_avg_diff2 , memset_avg_diff3;
    unsigned long long bzero_avg_diff1, bzero_avg_diff2 , bzero_avg_diff3;
    int x , i;;
    char buf[11];
    char big_buf[8192];

    memset_avg_diff1 = memset_avg_diff2 = memset_avg_diff3 = 0;
    bzero_avg_diff1 = bzero_avg_diff2 = bzero_avg_diff3 = 0;

    for( i =0 ; i < 1000000; ++i){
    //x test 
    start = rdtsc();
    memset(&x<span style="font-family: Arial, Helvetica, sans-serif;"> , 0</span> , sizeof(x));
    end = rdtsc();

    diff = end - start;
    memset_avg_diff1 += diff;
    //printf("x memset cpu circle : %llu
" , diff); start = rdtsc(); bzero(&x , sizeof(x)); end = rdtsc(); diff = end - start; bzero_avg_diff1 += diff; // printf("x bzero cpu circle : %llu
" , diff); //buff test start = rdtsc(); memset(buf, 0, sizeof(buf)); end = rdtsc(); diff = end - start; memset_avg_diff2 += diff; ///printf("buf memset cpu circle : %llu
" , diff); start = rdtsc(); bzero(&buf , sizeof(buf)); end = rdtsc(); diff = end - start; bzero_avg_diff2 += diff; //printf("buf bzero cpu circle : %llu
" , diff); //big_buff test start = rdtsc(); memset(big_buf , 0, sizeof(big_buf)); end = rdtsc(); diff = end - start; memset_avg_diff3 += diff; ///printf("buf memset cpu circle : %llu
" , diff); //printf("big buf memset cpu circle : %llu
" , diff); start = rdtsc(); bzero(&big_buf , sizeof(big_buf)); end = rdtsc(); diff = end - start; bzero_avg_diff3 += diff; } memset_avg_diff1 /= 1000000; memset_avg_diff2 /= 1000000; memset_avg_diff3 /= 1000000; bzero_avg_diff1 /= 1000000; bzero_avg_diff2 /= 1000000; bzero_avg_diff3 /= 1000000; printf("x memset cpu circle : %llu
" , memset_avg_diff1); printf("x bzero cpu circle : %llu
" , bzero_avg_diff1); printf("buf memset cpu circle : %llu
" , memset_avg_diff2); printf("buf bzero cpu circle : %llu
" , bzero_avg_diff2); printf("big_buf memset cpu circle : %llu
" , memset_avg_diff3); printf("big_buf bzero cpu circle : %llu
" , bzero_avg_diff3); return 0; }

テスト結果:
 root@VM-Ubuntu203004:~# gcc test.c
root@VM-Ubuntu203004:~# ./a.out
x memset cpu circle : 51
x bzero cpu circle : 61
buf memset cpu circle : 51
buf bzero cpu circle : 62
big_buf memset cpu circle : 622
big_buf bzero cpu circle : 631
root@VM-Ubuntu203004:~# ./a.out
x memset cpu circle : 51
x bzero cpu circle : 61
buf memset cpu circle : 51
buf bzero cpu circle : 63
big_buf memset cpu circle : 619
big_buf bzero cpu circle : 625
root@VM-Ubuntu203004:~# gcc -O3 test.c
root@VM-Ubuntu203004:~# ./a.out
x memset cpu circle : 39
x bzero cpu circle : 35
buf memset cpu circle : 39
buf bzero cpu circle : 35
big_buf memset cpu circle : 2123
big_buf bzero cpu circle : 2144
root@VM-Ubuntu203004:~# ./a.out
x memset cpu circle : 39
x bzero cpu circle : 35
buf memset cpu circle : 39
buf bzero cpu circle : 35
big_buf memset cpu circle : 2126
big_buf bzero cpu circle : 2117
結論は次のとおりです.
1、memsetはやはりbzeroより速く、-O 3最適化の場合、小オブジェクトを初期化し、memsetはbzeroより速くするが、追及する価値はない.
2、文字列メモリの場合、できるだけ最初の文字を使用してすべての文字をクリアする代わりにクリアします.
3、変数初期化のあるタイプに対して、クリア動作を避ける