RyuJITのSIMD関連コードリーディング(1)
しつこくこの話題。
System.Console.WriteLine("Vector<double>.Count=" + Vector<double>.Count); System.Console.WriteLine("Vector<float>.Count=" + Vector<float>.Count);の結果が
Vector<double>.Count=2 Vector<float>.Count=4になってる(要は、128ビットと判定されてる)
Re: Re: Re: OpenCLやる前にSIMD使い切れっていう幻想 - 猫とC#について書くmatarilloの雑記
ということで、RyuJITのコードを覗き見。
// Get the number of bytes in a SIMD Vector. unsigned getSIMDVectorRegisterByteLength() { #if defined(_TARGET_XARCH_) && !defined(LEGACY_BACKEND) if (canUseAVX()) { return YMM_REGSIZE_BYTES; } else { assert(canUseSSE2()); return XMM_REGSIZE_BYTES; } #else assert(!"getSIMDVectorRegisterByteLength() unimplemented on target arch"); unreached(); #endif }coreclr/src/jit/compiler.h#L6921-L6938
ふむ、canUseAVX()関数がtrueを返すなら、定数YMM_REGSIZE_BYTES(32バイト)が返ってくるようなコードになってますね。
では、canUseAVX()関数はどうなってるかというと。
bool canUseAVX() const { #ifdef FEATURE_AVX_SUPPORT return opts.compCanUseAVX; #else return false; #endif }coreclr/src/jit/compiler.h#L7030-L7037
どんどん深くなってきました。で、今度はopts.compCanUseAVXです。こちらはstructになってます。
opts.compCanUseAVX = false; if (((compileFlags & CORJIT_FLG_PREJIT) == 0) && ((compileFlags & CORJIT_FLG_USE_AVX2) != 0)) { static ConfigDWORD fEnableAVX; if (fEnableAVX.val(CLRConfig::EXTERNAL_EnableAVX) != 0) { opts.compCanUseAVX = true; if (!compIsForInlining()) { codeGen->getEmitter()->SetUseAVX(true); } } }coreclr/src/jit/compiler.cpp#L1608-L1621
だんだん面倒になってきたなあ。ConfigDWORD.val()はここで、CLRConfig::EXTERNAL_EnableAVXはここ。
いやまて、compileFlagsの方が重要か。
unsigned compileFlags = opts.eeFlags;
coreclr/src/jit/compiler.cpp#L1581
unsigned eeFlags; // flags passed from the EEcoreclr/src/jit/compiler.h#L7122
EE(Execution Engine: 実行エンジン)きたー!!!!
続きはまた今度!