インテル® FPGA SDK for OpenCL™プロ・エディション: プログラミング・ガイド

ID 683846
日付 4/01/2019
Public
ドキュメント目次

5.2.2. ネスト化されたループの結合

loop_coalesceプラグマを使用し、ループの機能に影響を与えずにネスト化されたループを1つのループに結合するよう、インテル FPGA SDK for OpenCLオフライン・コンパイラーに指示します。ループの結合は、コンパイラーにループ制御に必要なオーバーヘッドを削減するよう指示することにより、カーネルの使用領域を削減することができます。

ネスト化されたループを結合すると、コンポーネントのレイテンシーも低減されるため、カーネルの使用領域をさらに削減することも可能です。ただし場合によっては、ループを結合させることで重要なループを開始させるパスの間隔が長くなる場合があるため、ループの結合がカーネルすべてに適しているとは限りません。

NDRangeカーネルでは、loop_coalesceプラグマによりアノテートされていない場合でも、コンパイラーは自動的にループ結合を試みます。NDRangeカーネルでループを結合することにより、スループットが向上するとともに、カーネルの使用領域が低減します。loop_coalesceプラグマを使用すると、NDRangeカーネルにおけるループの自動結合を防ぐことができます。

ネスト化されたループを結合するには、次のようにプラグマを指定します。
#pragma loop_coalesce <loop_nesting_level>

<loop_nesting_level> パラメーターは、コンパイラーが結合を試みるネスト化されたループのレベル数をオプションで指定する整数です。<loop_nesting_level> パラメーターを指定しない場合、コンパイラーはネスト化されたループすべてを結合しようと試みます。

ネスト化されたループの例を以下に示します。
for (A)
  for (B)
 for (C) for (D)
 for (E)
ループ (A) の前にプラグマを配置すると、このループのネストレベルは次のように定義されます。
  • ループ (A) のループ・ネスト・レベルは1
  • ループ (B) のループ・ネスト・レベルは2
  • ループ (C) のループ・ネスト・レベルは3
  • ループ (D) のループ・ネスト・レベルは4
  • ループ (E) のループ・ネスト・レベルは3
指定したループ・ネスト・レベルによって、コンパイラーは異なるループ結合を試みます。
  • #pragma loop_coalesce 1をループ (A) に指定した場合、コンパイラーはこのネスト化されたループの結合を試みません。
  • #pragma loop_coalesce 2をループ (A) に指定した場合、コンパイラーはループ (A) と (B) の結合を試みます。
  • #pragma loop_coalesce 3を (A) に指定した場合、コンパイラーはループ (A)、(B)、(C)、(E)の結合を試みます。
  • #pragma loop_coalesce 4をループ (A) に指定した場合、コンパイラーはループ (A) からループ (E) すべてのループの結合を試みます。
重要: #pragma loop_coalesce 1をNDRangeカーネルのループに指定すると、そのループの自動ループ結合を防ぐことができます。

以下は、コンパイラーが2つのループを1つのループに結合する方法を簡単な例にて示しています。

下記はネスト化された単純なループです。
#pragma loop_coalesce
for (int i = 0; i < N; i++)
  for (int j = 0; j < M; j++)
    sum[i][j] += i+j;
コンパイラーは2つのループを結合し、次のような1つのループであるかのように実行します。
int i = 0;
int j = 0;
while(i < N){
  
  sum[i][j] += i+j;
  j++;

  if (j == M){
    j = 0;
    i++;
  }
}