最初のバージョンでキャッシュ ミスが発生するのはなぜですか?
Oli がコメントで指摘しているように。この質問には根拠がありません。データがすでにキャッシュにある場合、キャッシュ ミスは発生しません。
それはさておき、2 つの例の間でメモリ アクセスに違いはありません。そのため、それらの間のパフォーマンスの違いの要因にはなりません。
2 番目のバージョンは実際に 1 番目よりもパフォーマンスが優れていますか? なぜ ?
通常は、実際に測定することになります。しかし、この特定の例では、より高速になる可能性が高いと言えます。キャッシュ アクセスが改善されたからではなく、ループ展開が行われたからです。
あなたが行っている最適化は「ノード分割」と呼ばれcounter
、依存関係の連鎖を断ち切る目的で変数を分離します。
ただし、この場合、単純なリダクション操作を行っています。最新のコンパイラの多くは、このパターンを認識して、このノード分割を行うことができます。
それで、それはより速いですか?最も可能性が高い。ただし、コンパイラがそれを行うかどうかを確認する必要があります。
記録のために: Visual Studio 2010 でこれをテストしました。この最適化を実行できないこと
に非常に驚いています。
; 129 :
; 130 : int counter = 0;
; 131 :
; 132 : for (int i=0; i<n; i++)
mov ecx, DWORD PTR n$[rsp]
xor edx, edx
test ecx, ecx
jle SHORT $LN1@main
$LL3@main:
; 133 : {
; 134 : counter += myArray[i];
add edx, DWORD PTR [rax]
add rax, 4
dec rcx
jne SHORT $LL3@main
$LN1@main:
; 135 : }
Visual Studio 2010 は、この (簡単な) 例では「ノード分割」を実行できないようです...