インテルのみ表示可能 — GUID: mwh1391807501518
Ixiasoft
6.1. 最大ワーク・グループ・サイズまたは必要なワーク・グループ・サイズの指定
オフライン・コンパイラーは、コンパイル時および実行時に課される特定の制約に応じて、カーネルのデフォルトのワーク・グループ・サイズを想定しています。
オフライン・コンパイラーは、コンパイル時に次の制約を課します。
- reqd_work_group_size属性に値を指定すると、作業グループのサイズはこの値と一致する必要があります。
- max_work_group_size属性に値を指定すると、ワーク・グループ・サイズはこの値を超えてはなりません。
- reqd_work_group_sizeとmax_work_group_sizeの値を指定せず、カーネルに障壁がある場合、オフライン・コンパイラーのデフォルトの作業グループサイズは256です。
- 両方の属性に値を指定せず、カーネルにバリアが含まれていない場合、オフライン・コンパイラーはコンパイル時にワーク・グループ・サイズに制約を課すことはありません。
OpenCL™標準では、実行時に次の制約が課されます。
- 各ディメンションのワーク・グループ・サイズは、各ディメンションの要求されたNDRangeサイズに均等に分割する必要があります。
- ワーク・グループ・サイズは、 clGetDeviceInfo APIコールのCL_DEVICE_MAX_WORK_GROUP_SIZEおよびCL_DEVICE_MAX_WORK_ITEM_SIZESクエリで指定されたデバイス制約を超えてはなりません。
reqd_work_group_size属性とmax_work_group_size属性の両方に値を指定しない場合、ランタイムはデフォルトのワーク・グループ・サイズを次のように決定します。
- カーネルに障壁が含まれているかローカルのWork-Item IDを参照している場合、またはホストコードでclGetKernelWorkGroupInfoおよびclGetDeviceInfo API呼び出しを使用してワーク・グループ・サイズを照会すると、実行時はワーク・グループ・サイズからWork-Itemにデフォルトで実行します。
- カーネルに障壁がないか、ローカルWork-ItemIDを参照していない場合、またはホストコードがワーク・グループ・サイズを照会しない場合、デフォルトのワーク・グループ・サイズはグローバルNDRangeサイズです。
NDRangeカーネル(つまり、Single Work-Itemカーネルではない)をキューイングするときは、次の条件で明示的なワーク・グループ・サイズを指定します。
- カーネルがメモリーバリア、ローカルメモリー、またはローカルWork-ItemIDを使用している場合。
- ホストプログラムが作業グループのサイズを照会する場合。
カーネルでメモリーバリアが使用されている場合、次のいずれかの作業を実行して、ハードウェア・リソースを最小限に抑えます。
- reqd_work_group_size属性の値を指定します。
- max_work_group_size属性には、すべてのランタイム作業グループサイズ要求に対応する最小の作業グループサイズを割り当てます。
実行時にデフォルトより小さいワーク・グループ・サイズを指定すると、ハードウェアが過剰に消費される可能性があります。したがって、デフォルト以外のワーク・グループ・サイズが必要な場合、 max_work_group_size属性を指定して最大ワーク・グループ・サイズを設定します。すべてのカーネル呼び出しでワーク・グループ・サイズが一定のままである場合、 reqd_work_group_size属性を含めることによって、必要なワーク・グループ・サイズを指定します。reqd_work_group_size属性は、指定したワークグループごとのWork-Itemの数を管理するために、正確なハードウェア量を割り当てるようにオフライン・コンパイラーに指示します。この割り振りにより、ハードウェア・リソースが節約され、カーネルコンピューティング・ユニットの実装効率が向上します。 reqd_work_group_size属性を指定することにより、オフライン・コンパイラーが未知のサイズの作業グループをサポートするために追加のハードウェアを実装するのを防ぐこともできます。
たとえば、次のコードでは、ワークグループの固定サイズを64個のWork-Itemに割り当てることができます。
__attribute__((reqd_work_group_size(64,1,1))) __kernel void sum (__global const float * restrict a, __global const float * restrict b, __global float * restrict answer) { size_t gid = get_global_id(0); answer[gid] = a[gid] + b[gid]; }