Store Forwarding
2514 ワード
前述したように、新しい値がStore Bufferに存在するため、Cache lineから古い値を取得し、エラーを引き起こす問題をさらに解決していきます.
<>本文には現代CPUの構造図があり、一部は以下の通りである.
CPUロードメモリとStore Bufferとの間には相互作用がある.これがStore forwaringである.前述したように、CPU 0がb=a+1を実行すると、aの値がロードされ、store bufferにaの値があることがわかる.
store bufferから直接読み込んで計算し、最後に得られたbの値が正しい結果になります.
世界が急に美しくなったように、もっと良い最適化方法はありませんか.よく考えてみると、Store Bufferの空間も限られています.もしこのような状況が多すぎると、cache missの場合によくあります.store bufferがいっぱいになると、
面の命令は依然として前文のように待たなければならない.他のCPUが応答するまで、Store BufferからCacheに適用され、他のCPUが忙しい場合、または他のCPUがread validateメッセージを受信した後、自分のcache lineを失効させることも多くなる.
の時間がもったいないので、read validateメッセージを受け取ったら、直接返事をして、自分で適当なタイミングでゆっくり処理すればいいのです.
ところで、CPUを設計しているやつらはすごいとしか言いようがありません.彼らはもう一つのものを発明しました.Invalidate Queue、このキューはInvalidateメッセージをキャッシュして、すぐにInvalidate Acknowledgeメッセージをあげて、構造図にもこれを示しています.
1つのキュー.では、この問題は完璧に解決されました.
もう一つの例を見てみましょう.aとbの初期化はいずれも0である.a CPU 1のcacheにおいて、bはCPU 0のcacheにある.
CPU 0は、以下のコードを実行する.
a = 1;
b = 1;
CPU 1は、以下のコードを実行する.
while (b != 1);
assert (a == 1);
必ず成功すると断言しますか?次のような状況が発生したと仮定します.
1. CPU 0は、a=1を実行するが、aがcacheにないことを発見すると、「read invalidate」メッセージを発行し、aの値をstore bufferに存在させる.次にb=1を実行する.
2.CPU 1はb!=1の比較では、bの値を読み出し、cacheには含まれません.書き換えたくないので、「read」メッセージを1つだけ送信します.
3. CPU 0は、1をbのcache lineに直接書き込み、「read」メッセージを受信し、cache lineを共有として応答する.
4. CPU 1はbの値を受け取り、ループを終了し、断言を実行し、断言に失敗する.
5. CPU 1は、「read invalidate」のメッセージを受信するが、この時点では既に遅い.
以上の例から,CPU間のメッセージタイミングの不確実性,store bufferストレージ書き込み動作の遅延性により,この問題が共に起こり,これも一部のプロセッサで一般的に存在する問題,特に弱いメモリシーケンスのCPUであることが分かる.
だからMemory barriersは叫んだ.
Memroy barriers、すなわちメモリバリアは、Store Bufferのすべてのアイテムにタグを付けます.これにより、store操作がある場合、store bufferのアイテムにタグが付けられていることが判明し、cache lineに存在しても直接書くことはありません.
Cahce lineに入る代わりに、この操作はb=1であり、Store Bufferにも格納され、この項目はマークされず、Store Bufferでマークされた項目がすべてCachelineに適用されるまで待機し、これらの操作は正常に適用されます.メモリーは
barriersは本当にいいものですね.
(続き)
<>本文には現代CPUの構造図があり、一部は以下の通りである.
+--------------+
| CPU0 |
+--------------+
^ |
| |
| V
| +--------+
| | Store |
| | Buffer |
| +--------+
| |
| V
+--------------+
| Cache |
+--------------+
CPUロードメモリとStore Bufferとの間には相互作用がある.これがStore forwaringである.前述したように、CPU 0がb=a+1を実行すると、aの値がロードされ、store bufferにaの値があることがわかる.
store bufferから直接読み込んで計算し、最後に得られたbの値が正しい結果になります.
世界が急に美しくなったように、もっと良い最適化方法はありませんか.よく考えてみると、Store Bufferの空間も限られています.もしこのような状況が多すぎると、cache missの場合によくあります.store bufferがいっぱいになると、
面の命令は依然として前文のように待たなければならない.他のCPUが応答するまで、Store BufferからCacheに適用され、他のCPUが忙しい場合、または他のCPUがread validateメッセージを受信した後、自分のcache lineを失効させることも多くなる.
の時間がもったいないので、read validateメッセージを受け取ったら、直接返事をして、自分で適当なタイミングでゆっくり処理すればいいのです.
ところで、CPUを設計しているやつらはすごいとしか言いようがありません.彼らはもう一つのものを発明しました.Invalidate Queue、このキューはInvalidateメッセージをキャッシュして、すぐにInvalidate Acknowledgeメッセージをあげて、構造図にもこれを示しています.
1つのキュー.では、この問題は完璧に解決されました.
もう一つの例を見てみましょう.aとbの初期化はいずれも0である.a CPU 1のcacheにおいて、bはCPU 0のcacheにある.
CPU 0は、以下のコードを実行する.
a = 1;
b = 1;
CPU 1は、以下のコードを実行する.
while (b != 1);
assert (a == 1);
必ず成功すると断言しますか?次のような状況が発生したと仮定します.
1. CPU 0は、a=1を実行するが、aがcacheにないことを発見すると、「read invalidate」メッセージを発行し、aの値をstore bufferに存在させる.次にb=1を実行する.
2.CPU 1はb!=1の比較では、bの値を読み出し、cacheには含まれません.書き換えたくないので、「read」メッセージを1つだけ送信します.
3. CPU 0は、1をbのcache lineに直接書き込み、「read」メッセージを受信し、cache lineを共有として応答する.
4. CPU 1はbの値を受け取り、ループを終了し、断言を実行し、断言に失敗する.
5. CPU 1は、「read invalidate」のメッセージを受信するが、この時点では既に遅い.
以上の例から,CPU間のメッセージタイミングの不確実性,store bufferストレージ書き込み動作の遅延性により,この問題が共に起こり,これも一部のプロセッサで一般的に存在する問題,特に弱いメモリシーケンスのCPUであることが分かる.
だからMemory barriersは叫んだ.
Memroy barriers、すなわちメモリバリアは、Store Bufferのすべてのアイテムにタグを付けます.これにより、store操作がある場合、store bufferのアイテムにタグが付けられていることが判明し、cache lineに存在しても直接書くことはありません.
Cahce lineに入る代わりに、この操作はb=1であり、Store Bufferにも格納され、この項目はマークされず、Store Bufferでマークされた項目がすべてCachelineに適用されるまで待機し、これらの操作は正常に適用されます.メモリーは
barriersは本当にいいものですね.
(続き)