SPIR-V から ISPC へ: GPU 計算を CPU に変換する

同カテゴリーの次の記事

Unreal Engine* 4.19 の最適化にインテルのソフトウェア・エンジニアが協力

この記事は、インテル® デベロッパー・ゾーンに掲載されている「SPIR-V to ISPC: Convert GPU Compute to the CPU」の日本語参考訳です。


ゲーム業界における演算処理はグラフィックス処理ユニット (GPU) へ移行する傾向が高まっており、ゲームエンジンとスタジオではさまざまな計算タスク向けに GPU 計算シェーダーのポートフォリオが開発されています。しかし、それらの計算シェーダーを C/C++ によって再開発することなく、CPU 上で実行することが適していることがあります。これには、実装やデバッグ、空いている CPU サイクルの活用、CPU ベースのコンテンツ・スケーリング、ほかの CPU 上のゲームアセットとの CPU ベースのインタラクション、結果の決定論的な一貫性などを含む多くの理由があります。

この可能性に注目し、現代の CPU コアに組込まれている SIMD (Single Instruction, Multiple Data) ベクトルユニットを活用するのを支援するため、インテルではオープンソースの Khronos* SPIRV-Cross (英語) プロジェクトをベースとしたプロトタイプのトランスレーターの開発を始めました。これは、ISPC として知られるインテル® SPMD プログラム・コンパイラー (インテル® SPC) から入力および出力カーネルとして標準ポータブル中間言語 (SPIR-V1) を使用します。次の利用例で示すように、ispc.exe は C 形式のカーネルを使用して、インテル® ストリーミング SIMD 拡張命令 (インテル® SSE)、インテル® アドバンスト・ベクトル・エクステンション 2 (インテル® AVX2)、およびインテル® アドバンスト・ベクトル・エクステンション 512 (インテル® AVX-512) など複数の ISA をターゲットとする高度にベクトル化された CPU オブジェクト・ファイルを生成します。

このプロジェクトは、完全な機能とパフォーマンスを提供するソリューションというよりも、変換の開始点であると考えるべきです。プロジェクトでは、標準 SPIR-V の組込み関数、ビルトイン、および型のサブセットがサポートされていますが、ispc.exe のコア・パフォーマンス機能である一定 (スカラー) または可変 (ベクトル) 変数の概念を利用するように設計されています。これはテスト条件がスカラーである場合に、高価で拡散的なベクトル分岐を排除するような最適化を可能にします。

コードは、Sascha Willems’ Vulkan* リポジトリー (英語) の計算例や Microsoft* DirectX* 12 MiniEngine (英語) サンプルのパーティクル・システム計算シェーダーなど、一部のシェーダーで検証されています。

コードは GitHub* リポジトリー (英語) からダウンロードできますが、現在は Windows* システム上でのみ検証されています。GitHub* にある Readme には、実装とサポートされる機能に関する詳しいドキュメントが含まれています。

使用法

glslangValidator.exe -H -V -o test.spv test.comp

spirv-cross.exe --ispc --output test.ispc test.spv

ispc.exe -O2 test.ispc -o test.ispc.obj -h test.ispc.h --target=avx2 --opt=fast-math

API の使用例

ispc::raytracing_get_workgroup_size(workgroupSize[0], workgroupSize[1], workgroupSize[2]);

int32_t dispatch[3] = { textureComputeTarget.width / workgroupSize[0], textureComputeTarget.height / workgroupSize[1], 1 };
int32_t dispatch_count = dispatch[0] * dispatch[1];

concurrency::parallel_for<uint32_t>(0, dispatch_count, [&amp;](uint32_t dispatchID)
{
    int32_t workgroupID[3] = { dispatchID % dispatch[0], dispatchID / dispatch[1], 0 };
    ispc::raytracing_dispatch_single(workgroupID, dispatch, planeCount, *pPlanes, sphereCount, *pSpheres, *pUBO, resultImage);
}

このプロジェクトは、オリジナルの SPIRV-Cross Apache 2.0 ライセンス (英語) の元にオープソース化されており、皆さんの意見と支援をお待ちしています。

ゲームで ISPC を使用する詳細については、「ゲームの CPU ベクトル化にインテル® SPMD プログラム・コンパイラーを使用する」 (英語) の記事で紹介されています。

脚注:

  1. SPIR-V は Vulkan のデフォルトシェーダー言語であり、glslangValidator (英語) や shaderc (英語) コンパイラーなどのツールを使用して OpenGL* シェーディング言語 (GLSL) と高水準シェーディング言語 (HLSL) から生成することができます。

コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。

関連記事

  • Windows* ML: インテル® ハードウェア上での AI の高速化Windows* ML: インテル® ハードウェア上での AI の高速化 この記事は、インテル® デベロッパー・ゾーンに公開されている「Windows* Machine Learning: AI Acceleration on Intel® Hardware」の日本語参考訳です。 この記事の PDF 版はこちらからご利用になれます。 はじめに 人口知能 (AI) […]
  • Direct3D® 12 フリップモデルのスワップチェーンのサンプル・アプリケーションDirect3D® 12 フリップモデルのスワップチェーンのサンプル・アプリケーション この記事は、インテル® デベロッパー・ゾーンに公開されている「Sample Application for Direct3D 12 Flip Model Swap Chains」の日本語参考訳です。 この記事の PDF 版はこちらからご利用になれます。 サンプルコード D3D12 のほうが D3D11 […]
  • Direct3D 12 概要 パート 8: CPU の並列性Direct3D 12 概要 パート 8: CPU の並列性 この記事は、インテル® デベロッパー・ゾーンに公開されている「Direct3D 12 Overview Part 8: CPU Parallelism」の日本語参考訳です。 パート 7 では、ダイナミック・ヒープについて触れ、それがどのように CPU の並列性に役立つか説明しました。それでは、これまで紹介した D3D 12 […]
  • Direct3D 12 概要 パート 6: コマンドリストDirect3D 12 概要 パート 6: コマンドリスト この記事は、インテル® デベロッパー・ゾーンに公開されている「Direct3D 12 Overview Part 6: Command Lists」の日本語参考訳です。 これまで、バンドル、PSO、記述子ヒープ&テーブルを通して、D3D 12 がどのように CPU […]
  • Direct3D 12 概要 パート 5: バンドルDirect3D 12 概要 パート 5: バンドル この記事は、インテル® デベロッパー・ゾーンに公開されている「Direct3D 12 Overview Part 5: Bundles」の日本語参考訳です。 D3D 12 における新たしい描画コンテキストについては、説明を終えたと思います。これまで、D3D 12 がどのように 'ハードウェアに近い' […]