データ・プリフェッチとは、アプリケーションによってデータが必要になる前に、メモリーよりも高速なキャッシュにデータをロードしておくことです。データ・プリフェッチの動作はアーキテクチャーによって異なります。
IA-64 アーキテクチャー: インテル® コンパイラーは通常、-O1、-O2、および -O3 (Linux*)、または /O1、/O2、および /O3 (Windows*) が指定されると、プリフェッチ命令を発行します。
IA-32 およびインテル® 64 アーキテクチャー: プロセッサーは単純で、規則的なデータ・アクセス・パターンを特定し、ハードウェア・プリフェッチを行います。コンパイラーは、ハードウェア・プリフェッチが期待できない、より複雑なデータ・アクセス・パターンに対してプリフェッチ命令を発行します。
ほとんどの場合、プリフェッチ命令を発行するとパフォーマンスが向上します。ただし、プリフェッチ命令を発行することでアプリケーションのパフォーマンスが低下する場合もあります。このような場合、プリフェッチを調整します。コンパイラー・オプションでプリフェッチをオンまたはオフにすると、他の最適化はそのままでプリフェッチによるパフォーマンス低下の原因を追求するのに役立ちます。コンパイラー・オプションを使用したデータのプリフェッチに関する詳細は、「オプションを使用したプリフェッチ」を参照してください。
プリフェッチ命令を発行するには 2 つの方法があります。1 つはコンパイラー宣言子、もう 1 つはコンパイラー組み込み関数を使用する方法です。
PREFETCH 宣言子および NOPREFETCH 宣言子は、インテル® Itanium® プロセッサーでのみサポートされています。これらの宣言子は、データ・プリフェッチがメモリー参照に生成されるか、されないかを指定します。これは、コンパイラーが使用するヒューリスティックに影響します。
ループの前に PREFETCH A を置いて、ループ内で式 A(j) を使用する場合、コンパイラーはループ内の A(j+d) のプリフェッチを挿入します。d はデータをプリフェッチするための残りの反復回数で、コンパイラーによって決定されます。この宣言子は、最適化レベルが -O1 (Linux) または /O1 (Windows) よりも高い場合にサポートされます。-O2 および /O2 は、デフォルトの最適化レベルである点に注意してください。
例 |
---|
!DEC$ NOPREFETCH c !DEC$ PREFETCH a do i = 1, m b(i) = a(c(i)) + 1 enddo |
次の例は、IA-64 アーキテクチャーでのみ有効です。
例 |
---|
do j=1,lastrow-firstrow+1 i = rowstr(j) iresidue = mod( rowstr(j+1)-i, 8 ) sum = 0.d0 !DEC$ NOPREFETCH a,p,colidx do k=i,i+iresidue-1 sum = sum + a(k)*p(colidx(k)) enddo !DEC$ NOPREFETCH colidx !DEC$ PREFETCH a:1:40 !DEC$ PREFETCH p:1:20 do k=i+iresidue, rowstr(j+1)-8, 8 sum = sum + a(k)*p(colidx(k)) & + a(k+1)*p(colidx(k+1)) + a(k+2)*p(colidx(k+2)) & + a(k+3)*p(colidx(k+3)) + a(k+4)*p(colidx(k+4)) & + a(k+5)*p(colidx(k+5)) + a(k+6)*p(colidx(k+6)) & + a(k+7)*p(colidx(k+7)) enddo q(j) = sum enddo |
コンパイラー組み込み関数を挿入する前に、サポートされる他のコンパイラー・オプションと宣言子を試してみてください。コンパイラー組み込み関数は、コンパイラー・オプションやコンパイラー宣言子よりも、移植性および柔軟性が低くなります。
宣言子は、コンパイラーの最適化を有効にしますが、組み込み関数は最適化を実行します。宣言子を使用したプログラムは移植性が高いため、コンパイラーは別のプロセッサーに適用することができますが、組み込み関数を使用したプログラムを別のプロセッサーに適用するには、書き換えや移植が必要です。これは、組み込み関数がアセンブリー言語のプログラミングに近いためです。
コンパイラーは、組み込み関数サブルーチンの mm_prefetch をサポートしています。prefetch 宣言子がメモリーからのデータ・プリフェッチを有効にするのに対して、サブルーチン mm_prefetch は、1 つのメモリー・キャッシュ・ライン上の指定のアドレスからデータをプリフェッチします。mm_prefetch サブルーチンについては、「Language Reference」(英語) で説明されています。