Unreal Engine 4 でIntel Implicit SPMD Program Compilerを使う

はじめに

Unreal Engine 4で, Implicit SPMD Program Compiler (ISPC)を使用してみます. EngineのModuleのひとつで, Animation, Chaos, Niagaraなど至るところで使われています. 組み込みに難しいことはなく, 将来に渡ってサポートされる可能性が高いです.

組み込み

単純なサンプルで試してみます. まず, .Build.csにModuleを追加します. これで, ビルドに.ispcが含まれ, オブジェクトファイルが生成されます.

PrivateDependencyModuleNames.AddRange(new string[] { "IntelISPC" });

そして, 次のようなISPCTest.ispcを用意します. これは, Intelのサンプルのものです.

export void simple(uniform float vin[], uniform float vout[], uniform int count)
{
    foreach (index = 0 ... count) {
        float v = vin[index];
        if (v < 3.)
            v = v * v;
        else
            v = sqrt(v);
        vout[index] = v;
    }
}

UE4のActorを追加して, 毎フレーム次のコードを回してみます.

#if INTEL_ISPC
#include "ISPCTest.ispc.generated.h"
#endif

DECLARE_CYCLE_STAT(TEXT("AISPCTestActor_RunISPC"), STAT_AISPCTestActor_RunISPC, STATGROUP_ISPC);
void AISPCTestActor::RunISPC()
{
    SCOPE_CYCLE_COUNTER(STAT_AISPCTestActor_RunISPC);
    ispc::simple(vin, vout0, Count);
}
DECLARE_CYCLE_STAT(TEXT("AISPCTestActor_RunLoop"), STAT_AISPCTestActor_RunLoop, STATGROUP_ISPC);
void AISPCTestActor::RunLoop()
{
    SCOPE_CYCLE_COUNTER(STAT_AISPCTestActor_RunLoop);
    for (int32 i = 0; i < Count; ++i) {
        float v = vin[i];
        if(v < 3.) {
            v = v * v;
        } else {
            vout1[i] = FMath::Sqrt(v);
        }
    }
}

オブジェクトファイルと別に, ファイル名.ispc.generated.hというプロトタイプ宣言が生成されます. また, ISPCの関数は namespace ispcに入ります.
これで, ISPCを使用する最低限の環境ができました.

まとめ

サンプル程度だといくら計算回数を増やそうが, ただのループと変わりませんが, ちゃんと考えてあげれば速くなるでしょう.