私はパーティーに少し遅れましたが、すでに素晴らしい回答があります。しかし、私は、プロファイリングツール(Linux上)を使ってこの質問に実験的にどのように答えられるかを実証することで貢献できると考えました。
perf
ツールは、Ubuntu 10.10パッケージlinux-tools-common
で使用します。ここで
が、私はこの質問に答えるために書いた小さなCプログラムです:
// test.c
#define DIM 1024
int main()
{
int v[DIM][DIM];
unsigned i, j;
for (i = 0; i < DIM; i++) {
for (j = 0; j < DIM; j++) {
#ifdef ROW_MAJOR_ORDER
v[i][j] = 0;
#else
v[j][i] = 0;
#endif
}
}
return 0;
}
次に、2つの異なるバージョンでコンパイル:
$ gcc test.c -O0 -DROW_MAJOR_ORDER -o row-maj
$ gcc test.c -O0 -o row-min
注意を私は-O0
で無効な最適化をしたので、gccがチャンスを持っていませんより効率的にループを再編成することができます。
perf list
を実行すると、perf
で利用可能なパフォーマンス統計を表示できます。この場合、私たちはキャッシュミスに興味があります。これはイベントcache-misses
です。
$ perf stat -e cache-misses -r 100 ./row-min
Performance counter stats for './row-min' (100 runs):
286468 cache-misses (+- 0.810%)
0.016588860 seconds time elapsed (+- 0.926%)
$ perf stat -e cache-misses -r 100 ./row-maj
Performance counter stats for './row-maj' (100 runs):
9594 cache-misses (+- 1.203%)
0.006791615 seconds time elapsed (+- 0.840%)
そして今、我々は実験的に、あなたが実際にして二桁以上のキャッシュ・ミスを見ないことを確認しました:
今では、プログラムの各バージョンに何度も実行して平均を取るのと同じくらい簡単です「行マイナー」バージョン
参照先:「遅い」方法でCPUキャッシュを無駄に無効にしています。 – dlev
@dlev:これを回答として投稿しないでください。 –
dlevは担当者に関するものではないためです。 dlevは愛についてです – Robotnik