一部のコードを命令キャッシュにプリフェッチしたいと考えています。コードパスはめったに使用されませんが、まれに使用される場合に備えて、命令キャッシュまたは少なくとも L2 にある必要があります。これらのまれなケースについて、事前に通知があります。_mm_prefetch はコードで機能しますか? この使用頻度の低いコードをキャッシュに入れる方法はありますか? この問題については、移植性は気にしないので、asm でも構いません。
2 に答える
答えは、CPU アーキテクチャによって異なります。
とはいえ、gcc または clang を使用している場合は、__builtin_prefetch
命令を使用してプリフェッチ命令の生成を試みることができます。Pentium 3 以降の x86 タイプのアーキテクチャではPREFETCHh
、データ キャッシュ階層へのロードを要求する命令が生成されます。これらのアーキテクチャには L2 以上のキャッシュが統合されているため、役立つ場合があります。
関数は次のようになります。
__builtin_prefetch(const void *address, int locality);
locality
引数は 0 ~ 3 の範囲である必要があります。命令の一部にlocality
直接マップすると仮定すると、データを L2 以上のキャッシュにロードするよう要求する 1 または 2 を渡す必要があります。Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 2B: Instruction Set Reference, MZ (PDF) page 4-277 を参照してください。(他の巻はこちらから)h
PREFETCHh
を持たない別のコンパイラを使用している__builtin_prefetch
場合は、関数があるかどうかを確認してください_mm_prefetch
。その関数を取得するには、ヘッダー ファイルを含める必要がある場合があります。たとえば、OS X では、その関数とlocality
引数の定数は で宣言されていxmmintrin.h
ます。
コードをプリフェッチする (公式 [1] x86) 命令はなく、データのみです。これは、コード パスが事前にわかっているものの、ほとんど実行されず、コードのプリフェッチに大きなメリットがある、かなり奇妙なユース ケースだと思います。この特殊なケースのコードをプリロードすることには大きな利点があるという結論に達した場所を理解することは素晴らしいことです.長い時間だけでなく、プロセッサがコードをロードするための通常のメカニズムによってコードをプリフェッチする前に、実際にコードをロードするための予備のバスサイクルがあることも判断します。
prefetch
通常、I キャッシュと D キャッシュの間で共有される L2 にフェッチする命令を使用できる場合があります。
[1] プロセッサがキャッシュ コンテンツを操作できるようにする「秘密の」命令がいくつかあることは知っていますが、それらをユーザー モード コードで使用できたとしても、多くの余分な作業が必要になるため [そして、これは一部のカーネル モード コードではありません]。