SYCL* アプリケーションの最適化

oneAPI は、CPU、GPU、FPGA など複数のアクセラレーターで実行できる機能コードを有効にします。ただし、コードはアクセラレーター全体で最適ではない可能性があります。パフォーマンスの目標を達成するには 3 段階の最適化を行うことを推奨します。

  1. アクセラレーター全体に適用される一般的な最適化を行います。

  2. 優先するアクセラレーターに対して積極的に最適化を行います。

  3. ステップ 1 と 2 を組み合わせてホストコードを最適化します。

最適化とは、ボトルネック (ほかのコードセクションに比べて実行時間が長いコード領域) を排除する作業です。これらのセクションは、デバイスまたはホストで実行できます。最適化では、インテル® VTune™ プロファイラーなどのプロファイル・ツールを使用して、コード内のボトルネックを特定します。

ここでは、最初のステップであるアクセラレーター全体に適用される一般的な最適化を検討します。デバイス固有の最適化、デバイス固有のベスト・プラクティス (ステップ 2)、およびホストとデバイス間の最適化 (ステップ 3 ) については、『インテル® oneAPI ツールキットの FPGA 最適化ガイド』 (英語) などのデバイス固有の最適化ガイドで詳しく説明されています。この節では、アクセラレーターにオフロードするカーネルがすでに決定されていることを前提としています。および単独のアクセラレーターでワークが完了することを想定しています。このガイドは、ホストとアクセラレーター間、またはホストと複数の/異なるアクセラレーター間のワークの分割については考慮していません。

アクセラレーター全体に適用される一般的な最適化は次の 4 つに分類されます。

  1. 高レベルな最適化

  2. ループ関連の最適化

  3. メモリー関連の最適化

  4. SYCL* 固有の最適化

次の節では上記の最適化のみをカバーします。これらの最適化を実際にコードに反映する方法の詳細は、オンラインや一般に入手できるコード最適化関連の資料で見付けることができます。ここでは、SYCL* 固有の最適化に関する詳細を示します。

高レベルの最適化ヒント

  • 並列ワークの量を増やします。処理要素を十分に活用するには、処理要素よりも多くのワークが必要です。

  • カーネルのコードサイズを最小化します。これにより、アクセラレーターの命令キャッシュにカーネルが保持されます。

  • カーネルのロードバランスを取ります。実行時間の長いカーネルはボトルネックとなり、ほかのカーネルのスループットに影響する可能性があるため、カーネル間の実行時間は大きく異ならないようにします。

  • 高コストの関数は避けてください。実行時間が長い関数は、ボトルネックとなる可能性があるため呼び出さないでください。

SYCL* 固有の最適化

  • 可能であれば、work-group サイズを指定します。属性 [[cl::reqd_work_group_size(X, Y, Z)]] (X、Y、Z は Nd-range の整数次元) を使用して、work-group のサイズを設定できます。コンパイラーはこの情報を利用して積極的な最適化を行うことができます。

  • 可能であれば、-Xsfpc オプションの使用を検討してください。このオプションは、可能な場合は常に中間の浮動小数点丸め操作と変換を排除して、精度を維持するため追加ビットをキャリーします。

  • -Xsno-accessor-aliasing オプションの使用を検討してください。このオプションは、SYCL* カーネルのアクセサー引数間の依存関係を無視します。