これは、コンパイラ(そのバージョン)、最適化レベル、および CPU によって異なります。どうやら、ほとんどの時間が費やされmalloc
ているので、ループから移動して を増やしSIZE
ました。
16G バイトの RAM を搭載した i3770K プロセッサで GCC 4.8.1 を使用して Debian/Sid を試しています。
と
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#define SIZE 1024*1024*1024
int main ()
{
struct timeval start, end;
clock_t startcl, endcl;
int k, i;
int *arr = (int *) malloc (SIZE * sizeof (int));
if (!arr) { perror("malloc"); exit(EXIT_FAILURE); };
for (k = 1; k <= 1024; k *= 2) {
gettimeofday (&start, NULL);
startcl = clock();
for (i = 0; i < SIZE; i += k)
arr[i] *= 3;
gettimeofday (&end, NULL);
endcl = clock();
printf ("K = %d, time = %ld, cpu clock=%ld microsec\n", k,
(end.tv_sec - start.tv_sec) * 1000000
+ (end.tv_usec - start.tv_usec),
(long) (endcl - startcl));
}
free (arr);
return 0;
}
そしてそれをコンパイルしてgcc -Wall -mtune=native -O3 ./wilsonwen.c -o ./wilsonwen-O3
実行します:
K = 1, time = 696074, cpu clock=680000 microsec
K = 2, time = 361173, cpu clock=360000 microsec
K = 4, time = 341920, cpu clock=340000 microsec
K = 8, time = 341767, cpu clock=340000 microsec
K = 16, time = 342065, cpu clock=340000 microsec
K = 32, time = 224502, cpu clock=230000 microsec
K = 64, time = 119544, cpu clock=120000 microsec
K = 128, time = 51089, cpu clock=50000 microsec
K = 256, time = 26447, cpu clock=20000 microsec
K = 512, time = 14104, cpu clock=20000 microsec
K = 1024, time = 8385, cpu clock=10000 microsec
これは、あなたが言及したブログとより一致しています。malloc
外側のループの外に移動することは非常に重要です (そうしないと、基盤となるシステムコールがかなりの時間を消費してk
いるため、キャッシュ効果が見られません)。malloc
mmap
時間がかかる理由を説明できませんk=1
(おそらく、malloc
-ed メモリがページ フォールトによって RAM に取り込まれるためですか?)。for (i=0; i<SIZE/1024; i++) arr[i] = i;
ループの前に「ページをプリフェッチ」するループを追加しても、for (k
for の時間は for のk=1
約 2 倍ですk=2
。Igor Ostrovsky のブログで言及されているk=2
toの高原が見られます。k=16
で置き換えることはあまり重要malloc
ではありません。コンパイルに (4.8) の代わりに (3.2)calloc
を使用すると、非常に類似したタイミング結果が得られます。clang
gcc
最適化は非常に重要です。 を試してgcc -Wall -O0 ./wilsonwen.c -o ./wilsonwen-O0
実行すると、プラトーが表示されなくなります (これは を使用しても表示されます-O1
)。gcc
最適化フラグがないと非常に貧弱なマシンコードが吐き出されることはよく知られています。
ベンチマークの一般的なルールは、コンパイラの最適化を有効にすることです。