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

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

6.7. SoCをターゲットとするOpenCL カーネルへの共有メモリーの割り当て

インテルでは、 インテル® SoCで動作するOpenCL™カーネルは、FPGA DDRメモリーではなく共有メモリーにアクセスすることを推奨しています。 FPGA DDRメモリーには、非常に高い帯域幅でカーネルがアクセス可能です。ただし、ARM® CPUからFPGA DDRメモリーへの読み出しおよび書き込み動作は、ダイレクト・メモリー・アクセス (DMA) を使用していないため非常に低速です。FPGA DDRメモリーは、テスト目的でカーネル間または単一のカーネル内で一時データを渡すためだけに予約ください。
注:
  • カーネル間の共有バッファーは揮発性としてマークし、あるカーネルによるバッファーの変更が他のカーネルも認識できるようにしてください。
  • 共有メモリーにアクセスするにはホストコードの変更のみが必要です。カーネルコードの変更は必要ありません。
  • ライブラリー関数mallocまたはnew演算子で、物理的に共有されたメモリーを割り当てることはできません。また、CL_MEM_USE_HOST_PTRフラグは共有メモリーでは機能しません。

    DDRメモリーでは、共有メモリーは物理的に連続している必要があります。FPGAは、SG-DMAコントローラー・コアなしでは実質的に連続したメモリーを消費することができません。malloc関数およびnew演算子は、実質的に連続したメモリーへアクセスするためのものです。

  • 共有メモリーのCPUキャッシュは無効になっています。
  • 共有メモリーを使用する際は、データのコピー1つがホストとカーネルの両方で使用されます。このメモリーを使用すると、OpenCLメモリーの呼び出しは、バッファー読み取り、バッファー書き込み、マッピングおよびアンマッピングに対し、ゼロコピー転送で実行されます。
ARM CPUとFPGAは、共有メモリーに同時にアクセスできます。clEnqueueReadBufferおよびclEnqueueWriteBuffer呼び出しをホストコードに含め、FPGAまたはCPUにデータを認識させる必要はありません。
  • 共有メモリーの割り当てとアクセスには、次の例のようなホストコードを構築します。
    cl_mem src = clCreateBuffer(…, CL_MEM_ALLOC_HOST_PTR, size, …);
    int *src_ptr  = (int*)clEnqueueMapBuffer  (…, src, size, …);
    *src_ptr = input_value; //host writes to ptr directly
    clSetKernelArg (…, src);
    clEnqueueNDRangeKernel(…);
    clFinish();
    printf (“Result = %d\n”, *dst_ptr); //result is available immediately
    clEnqueueUnmapMemObject(…, src, src_ptr, …);
    clReleaseMemObject(src); // actually frees physical memory
    
    CONFIG_CMA_SIZE_MBYTESカーネル・コンフィグレーション・オプションを含め、割り当てに有効な共有メモリーの最大総量を制御することができます。実際には、割り当てられた共有メモリーの総量は、CONFIG_CMA_SIZE_MBYTESの値よりも小さくなります。
    重要:
    1. ターゲットボードに複数のDDRメモリーバンクがある場合、clCreateBuffer(..., CL_MEM_READ_WRITE, ...)関数は、メモリーを非共有DDRメモリーバンクに割り当てます。ただし、FPGAが共有メモリーである単一DDRバンクへアクセスできる場合、clCreateBuffer(..., CL_MEM_READ_WRITE, ...) は、CL_MEM_ALLOC_HOST_PTRフラグを使用するのと同様に、メモリーを共有メモリーに割り当てます。
    2. clCreateBuffer(..., CL_MEM_ALLOC_HOST_PTR, size, ...)関数で要求する共有メモリーは、Linux OpenCLカーネルドライバーに割り当てられ、Linuxカーネルの連続したメモリー割り当て (CMA) 機能に依存します。CMAを有効にしコンフィグレーションする方法に関しては、Intel FPGA SDK for OpenCL Intel Arria 10 SoC Development Kit Reference Platform Porting GuideRecompiling the Linux Kernel for the Intel Arria 10 SoC Development Kit およびCompiling and Installing the OpenCL Linux Kernel Driverの章を参照ください。
  • 共有ハード・プロセッサー・システム (HPS) DDRからFPGA DDRへの効率的なデータ転送に向け、memcpy関数を実行するカーネルを次のように含めます。
    __attribute__((num_simd_work_items(8)))
    mem_stream(__global uint * src, __global uint * dst)
    {
        size_t gid = get_global_id(0);
        dst[gid] = src[gid];
    }
    
    重要: CL_MEM_ALLOC_HOST_PTRフラグを使用し、srcポインターをHPS DDRに共有メモリーとして割り当てます。
  • ホストがコンスタント・メモリーを共有HPS DDRシステムに割り当て、カーネル実行後にそれを変更すると、変更が有効にならない可能性があります。その結果、続くカーネル実行に古いデータが使用される可能性があります。カーネルの実行に古いコンスタント・メモリーが使用されないようにするため、次のいずれかを実行してください。
    1. コンスタント・メモリーの初期化後は、それを変更しない
    2. 複数の__constantデータセットが必要な場合、複数のコンスタント・メモリー・バッファーを作成する
    3. 可能であれば、アクセラレーター・ボードのFPGA DDRにコンスタント・メモリーを割り当てる