リトルの法則により、特定のレイテンシーと特定のレベルの同時実行でデータを転送できる速度が制限されることに気付きました。何かをより速く転送したい場合は、より大きな転送、「実行中」の転送の増加、または待ち時間の短縮のいずれかが必要です。RAM から読み取る場合、同時実行性は Line Fill Buffer の数によって制限されます。
ロードが L1 キャッシュをミスすると、Line Fill Buffer が割り当てられます。最新の Intel チップ (Nehalem、Sandy Bridge、Ivy Bridge、Haswell) は、コアあたり 10 個の LFB を備えているため、コアあたりの未解決のキャッシュ ミスは 10 個に制限されています。RAM レイテンシが 70 ns (妥当) で、各転送が 128 バイト (64B キャッシュ ラインとそのハードウェア プリフェッチ ツイン) の場合、コアあたりの帯域幅は 10 * 128B / 75 ns = ~16 GB/s に制限されます。シングルスレッドStreamなどのベンチマークは、これがかなり正確であることを確認しています。
レイテンシを短縮する明白な方法は、RAM から読み取る必要がないように、PREFETCHT0、PREFETCHT1、PREFETCHT2、または PREFETCHNTA などの x64 命令を使用して目的のデータをプリフェッチすることです。しかし、それらを使用しても何も高速化できませんでした。問題は、__mm_prefetch() 命令自体が LFB を消費するため、それらにも同じ制限が適用されることです。ハードウェア プリフェッチは LFB に触れませんが、ページの境界を越えることもありません。
しかし、私はこれがどこにも文書化されているのを見つけることができません。私が見つけた最も近いものは、15 年前の記事で、Pentium III でのプリフェッチは Line Fill Buffers を使用すると述べています。それ以来、状況が変わったのではないかと心配しています。また、LFB は L1 キャッシュに関連付けられていると思われるため、L2 または L3 へのプリフェッチでそれらが消費される理由がわかりません。それでも、私が測定した速度は、これが事実であることと一致しています.
では、これらの 10 個の Line Fill Buffer のいずれかを使い果たすことなく、メモリ内の新しい場所からフェッチを開始し、リトルの法則を回避してより高い帯域幅を実現する方法はありますか?