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

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

5.4.5.2. ブロッキングのチャネル書き込みの実装

write_channel_intel API呼び出しは、チャネルを介したデータ送信を可能にします。
ブロッキングのチャネル書き込みの実装には、次のwrite_channel_intel関数シグネチャーを使用します。
void write_channel_intel (channel <type> channel_id, const <type> data);

以下に詳細を説明します。

channel_idは、チャネルが接続するバッファーを識別します。また、対応する読み取りチャネル (read_channel_intel) のchannel_idと一致しなければなりません。

dataは、チャネル書き込み動作がチャネルに書き込むデータです。

<Type> は、チャネルのデータ幅を定義します。OpenCL™変換規則に従い、カーネルがチャネルに書き込むデータが、<type> に変換できるようにしてください。

以下に、write_channel_intel API呼び出しを実装するコード例を示します。
//Defines chan, a kernel file-scope channel variable.
channel long chan;

/*Defines the kernel which reads eight bytes (size of long) from global memory, and passes this data to the channel.*/ 
__kernel void kernel_write_channel( __global const long * src ) {
  for (int i = 0; i < N; i++) {
  //Writes the eight bytes to the channel.
  write_channel_intel(chan, src[i]);
  }
}
注意:
write_channel_intel API呼び出しを使用しチャネルを介してデータを送信する際は、チャネルの容量がフルの場合 (FIFOバッファーがデータでフルの場合) カーネルがストールし、FIFOバッファーのデータスロットが最低1つ利用可能になるまで待機することに注意してください。 インテル® FPGA Dynamic Profiler for OpenCL™ を使用し、チャネルのストールを確認してください。

ノンブロッキングのチャネル書き込みの実装

ノンブロッキングのチャネル書き込みを行うと、フルの状態のFIFOバッファーに書き込み、FIFOバッファーのスロットが利用可能になるまでカーネルがストールすることのないアプリケーションが容易にできるようになります。 ノンブロッキングのチャネル書き込みは、データがチャネルに正常に書き込まれた (チャネルがフルではなかった) ことを示すブール値を返します。

アプリケーションにデータ・プロデューサーが1つと、同一のワーカーが2つあるシナリオを例とします。各ワーカーがメッセージの処理に要する時間は、データの内容によって異ると想定します。この場合、一方のワーカーはビジー状態で、もう一方のワーカーはフリーの状態になる可能性があります。ノンブロッキングの書き込みは、両方のワーカーがビジー状態になるワークの分配を促進します。

ノンブロッキングのチャネル書き込みを実装するには、次のwrite_channel_nb_intel関数シグネチャーを含めます。
bool write_channel_nb_intel(channel <type> channel_id, const <type> data);
次に示すコードのカーネルproducerは、ノンブロッキングのチャネル書き込み拡張を使用し、ワークの分配を促進しています。
channel long worker0, worker1;
__kernel void producer( __global const long * src ) {
  for(int i = 0; i < N; i++)  {
        
    bool success = false;
    do {
      success = write_channel_nb_intel(worker0, src[i]);
      if(!success) {
        success = write_channel_nb_intel(worker1, src[i]);
      }
    }
    while(!success);
  }
}