この節では、ハードウェア固有のコンパイラー・ディレクティブをアルファベット順に説明します。特に記載のない場合、ディレクティブはどのハードウェアでも機能します。この節では、以下のディレクティブを説明します。
CACHE_ZERO | LIGHT_SYNC |
ISYNC | PREFETCH |
CACHE_ZERO ディレクティブは、マシン・インストラクション dcbz (data cache block set to zero) を起動します。この命令は、指定された変数に対応するデータ・キャッシュ・ブロックをゼロに設定します。このディレクティブは、慎重に使用してください。
構文
>>-CACHE_ZERO--(--cv_var_list--)------------------------------->< |
例
以下の例では、0 にしたいキャッシュ・ブロックに配列 ARRA がすでにロードされていると想定します。次に、キャッシュ・ブロック内のデータがゼロに設定されます。
real(4) :: arrA(2**5) ! .... !IBM* CACHE_ZERO(arrA(1)) ! set data in cache block to zero
ISYNC ディレクティブを使用すると、すべての先行する命令が完了した後に、プリフェッチされた命令を破棄することができます。後続の命令は、ストレージからフェッチまたは再フェッチを行って、直前の命令のコンテキストで実行します。ディレクティブは、ISYNC を実行するプロセッサーにのみ影響します。
構文
>>-ISYNC------------------------------------------------------->< |
LIGHT_SYNC ディレクティブは、LIGHT_SYNC ディレクティブを実行したプロセッサーで新しい命令を実行できるようになる前に、LIGHT_SYNC の前のすべての命令が確実に完了するようにします。これにより、 LIGHT_SYNC が各プロセッサーからの確認を待たなくなるため、パフォーマンスには最低限の影響しか与えずに複数のプロセッサー間で同期化できます。
構文
>>-LIGHT_SYNC-------------------------------------------------->< |
プリフェッチを使用して、データが参照される前に、データをメイン・メモリーからキャッシュにロードするようコンパイラーに指示することができます。 POWER3 以上のハードウェアによって自動的に行われるプリフェッチもありますが、コンパイラー支援ソフトウェア・プリフェッチは、ソース・コードの中で検出される情報を使用するため、このディレクティブを使用すればキャッシュ・ミスの数を大幅に減らすことができます。
XL Fortran では、コンパイラー支援ソフトウェア・プリフェッチ用に、次の 5 つのディレクティブが提供されています。
構文
PREFETCH ディレクティブには、以下の形式があります。
>>-PREFETCH_BY_LOAD--(--prefetch_variable_list--)-------------->< |
>>-PREFETCH_FOR_LOAD--(--prefetch_variable_list--)------------->< |
>>-PREFETCH_FOR_STORE--(--prefetch_variable_list--)------------>< |
>>-PREFETCH_BY_STREAM_BACKWARD--(--prefetch_variable--)-------->< |
>>-PREFETCH_BY_STREAM_FORWARD--(--prefetch_variable--)--------->< |
規則
PREFETCH_BY_STREAM_BACKWARD、PREFETCH_BY_STREAM_FORWARD、 PREFETCH_FOR_LOAD および PREFETCH_FOR_STORE ディレクティブを使用するには、 PowerPC ハードウェア用にコンパイルする必要があります。
変数をプリフェッチする時は、変数アドレスが入っているメモリー・ブロックがキャッシュにロードされます。メモリー・ブロックは、キャッシュ・ラインのサイズと同じです。キャッシュにロードする変数はメモリー・ブロックのどこにあってもかまわないので、配列のすべてのエレメントをプリフェッチできないこともあります。
これらのディレクティブは、実行可能構造体を入れることのできるソース・コードのどこにあってもかまいません。
これらのディレクティブを使用すると、プログラムの実行時オーバーヘッドが増えることがあります。したがって、ディレクティブを使用するのは必要なときだけにしてください。
プリフェッチ・ディレクティブの効果を最大化するために、単一のプリフェッチの後、または一連のプリフェッチの最後に、 LIGHT_SYNC ディレクティブを指定することをお勧めします。
例
例 1: この例は、PREFETCH_BY_LOAD、PREFETCH_FOR_LOAD、および PREFETCH_FOR_STORE ディレクティブの有効な使用法を示しています。
この例は、キャッシュ・ラインのサイズは 64 バイトであり、プログラムの開始時には宣言済みデータ項目はキャッシュに存在していないという前提になっています。ディレクティブを使用することについての理論的解釈は、次のとおりです。
PROGRAM GOODPREFETCH REAL*4 A, B, C, TEMP REAL*4 ARRA(2**5), ARRB(2**10), ARRC(2**5) INTEGER(4) I, K ! Bring ARRA into cache for writing. !IBM* PREFETCH_FOR_STORE (ARRA(1), ARRA(2**4+1)) ! Bring ARRC into cache for reading. !IBM* PREFETCH_FOR_LOAD (ARRC(1), ARRC(2**4+1)) ! Bring all variables into the cache. !IBM* PREFETCH_BY_LOAD (A, B, C, TEMP, I , K) ! A subroutine is called to allow clock cycles to pass so that the ! data is loaded into the cache before the data is referenced. CALL FOO() K = 32 DO I = 1, 2 ** 5 ! Bring ARRB(I*K) into the cache !IBM* PREFETCH_BY_LOAD (ARRB(I*K)) A = -I B = I + 1 C = I + 2 TEMP = SQRT(B*B - 4*A*C) ARRA(I) = ARRC(I) + (-B + TEMP) / (2*A) ARRB(I*K) = (-B - TEMP) / (2*A) END DO END PROGRAM GOODPREFETCH
例 2: この例は、キャッシュ・ラインのサイズの合計が 256 バイトであり、初期状態では、宣言済みデータ項目はキャッシュまたはレジスターに存在していないことを想定しています。また、配列 ARRA および ARRC のすべてのエレメントが、キャッシュに読み込まれます。
PROGRAM PREFETCH_STREAM REAL*4 A, B, C, TEMP REAL*4 ARRA(2**5), ARRC(2**5), ARRB(2**10) INTEGER*4 I, K ! All elements of ARRA and ARRC are read into the cache. !IBM* PREFETCH_BY_STREAM_FORWARD(ARRA(1)) ! You can substitute PREFETCH_BY_STREAM_BACKWARD (ARRC(2**5)) to read all ! elements of ARRA and ARRC into the cache. K = 32 DO I = 1, 2**5 A = -i B = i + 1 C = i + 2 TEMP = SQRT(B*B -4*A*C) ARRA(I) = ARRC(I) + (-B + TEMP) / (2*A) ARRB(I*K) = (-B -TEMP) / (2*A) END DO END PROGRAM PREFETCH_STREAM
関連情報
反復カウントの大きなループへのプリフェッチ技法の適用については、STREAM_UNROLL ディレクティブを参照してください。