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

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

5.12.1. アキュムレーターを推論するためのプログラミング手法

単一サイクル浮動小数点アキュムレーター機能の活用は、カーネルコードのアキュムレーターの記述を変更し効率を改善したり、プログラミングの制約を回避したりすることで行うことができます。

複数のループを使用するアキュムレーターの記述

複数のループを使用し、一部のループを展開した状態でアキュムレーターを記述する場合を以下に示します。

float acc = 0.0f;
for (i = 0; i < k; i++) {
    #pragma unroll
    for(j=0;j < 16; j++)
        acc += (x[i+j]*y[i+j]);
}

この場合、-fp-relaxed インテル® FPGA SDK for OpenCL™オフライン・コンパイラー・コマンド・オプションでカーネルをコンパイルし、累積が公開されるようにオフライン・コンパイラーが操作を再配置できるようにすることが重要です。-fp-relaxedでカーネルをコンパイルしない場合、アキュムレーターの構成は高いイニシエーション・インターバル (II) をともなうことになります。イニシエーション・インターバルは、連続するループ反復の開始から開始までのサイクル数です。イニシエーション・インターバルの値が大きいほど、アキュムレーター構造体が次のループ反復を処理するまでの時間が長くなります。

複数ループのアキュムレーターの記述変更

-fp-relaxedオフライン・コンパイラーのコマンドオプションでアキュムレーターの記述をコンパイルできない場合は、コードを書き換え累積を公開します。

上記コード例の場合は、次のように書き換えます。

float acc = 0.0f;
for (i = 0; i < k; i++) {
    float my_dot = 0.0f;
    #pragma unroll
    for(j=0;j < 16; j++)
        my_dot += (x[i+j]*y[i+j]);
    acc += my_dot;
}

変数またはゼロ以外の初期値を含むアキュムレーターの記述変更

ゼロ以外の値で始まるアキュムレーターの記述にオフセットを適用する場合を下に示します。

float acc = array[0];
for (i = 0; i < k; i++) {
    acc += x[i];
}

アキュムレーター・ハードウェアは、記述に変数またはゼロ以外の初期値をサポートしないため、記述を書き換える必要があります。

float acc = 0.0f;
for (i = 0; i < k; i++) {
    acc += x[i];
}
acc += array[0];

上記のように記述を書き換えると、カーネルはループでアキュムレーターを使用できるようになります。その後のループ構造には、array[0]のインクリメントが続きます。