0

単一の関数のベンチマークに使用される小さなベンチマークライブラリをCで作成しています。voidそれが機能する方法は、パラメーターと反復回数のない関数へのポインターをベンチマーク関数に提供することです。次に、関数は次のstruct情報を含むを返します。

ただし、個々の結果を見ると、最初の呼び出しに多くの時間がかかり、その後の呼び出しにかかる時間はごくわずかであることがわかります。

だから私は疑問に思っています:

  1. これは命令キャッシュによるものですか?
  2. 最初の質問に「はい」の場合、ベンチマークツールは一般的にこれにどのように準拠していますか?最初の呼び出しは除外されますか?
  3. 最初の質問に「はい」の場合、キャッシュが関数に適用されない場合はありますか?
  4. 最初の質問に「はい」の場合、キャッシュは関数全体または関数のセグメントで発生しますか?
  5. 最初の質問に「はい」の場合、他に何か読んで理解を深める必要があると考えるべきことはありますか?

データとコード

時間を取得する関数:

double currentTime()
{
    struct timeval time;
    struct timezone timezone;
    gettimeofday(&time, &timezone);
    return time.tv_sec + time.tv_usec * 1e-6;
}

テスト結果:

0.000319
0.000000
0.000000
0.000000
0.000001
0.000000
0.000000
0.000000
0.000000
0.000000
Total time: 0.000320
Average time: 0.000032
Worst time: 0.000319
Best time: 0.000000

フラグを最適化しない場合の結果:

13.425430
13.349757
13.482863
13.129472
13.020705
13.672982
13.027595
13.139602
13.028962
13.107892
Total time: 132.385260
Average time: 13.238526
Worst time: 13.672982
Best time: 13.020705

この結果を生成するテスト中の関数:

void test()
{
    unsigned int i = 0;
    while(i++ < UINT_MAX){}
}

ファイルを作成します。

CC = gcc
MAIN = main.c
SOURCES = lib/tb_time_handling.c lib/tb_rendering.c tb_benching.c
OUTPUT = main
FLAGS = -Wall -pedantic -O2

all: main

main: 
    $(CC) $(MAIN) $(SOURCES) -o $(OUTPUT) $(FLAGS)

すべてのコードを含むGithubリポジトリ:

https://github.com/Ancide/TinyBench

編集:コンパイラとコンパイラフラグについて言及するのを忘れた

編集2:誰かがすべてを見たい場合に備えて、すべてのコードを含むgitリポジトリを追加しました

編集3:O2フラグなしで結果を追加

4

1 に答える 1

1

これは、仮想メモリ オペレーティング システムでは正常です。関数への最初の呼び出しは、コードを実行可能ファイルから RAM にロードするページ フォールトを生成する傾向があります。実際のコードのパフォーマンスに関心がある場合は、最初の呼び出しを無視します。現実的なパフォーマンス測定に関心がある場合は、無視しないでください。

于 2011-10-19T12:21:11.160 に答える