RyuJIT で SIMD 命令を使用すると、どのような高速化が得られるかをテストしていますが、予期しない逆アセンブリ命令が表示されます。このコードは、RyuJIT チームの Kevin Frei によるこのブログ投稿と関連する投稿 (こちら) に基づいています。関数は次のとおりです。
static void AddPointwiseSimd(float[] a, float[] b) {
int simdLength = Vector<float>.Count;
int i = 0;
for (i = 0; i < a.Length - simdLength; i += simdLength) {
Vector<float> va = new Vector<float>(a, i);
Vector<float> vb = new Vector<float>(b, i);
va += vb;
va.CopyTo(a, i);
}
}
私が照会している逆アセンブリのセクションは、配列の値をVector<float>
. 逆アセンブルのほとんどは、Kevin と Sasha の投稿にあるものと似ていますが、逆アセンブルに表示されないいくつかの追加の手順 (混乱した注釈と共に) を強調しています。
;// Vector<float> va = new Vector<float>(a, i);
cmp eax,r8d ; <-- Unexpected - Compare a.Length to i?
jae 00007FFB17DB6D5F ; <-- Unexpected - Jump to range check failure
lea r10d,[rax+3]
cmp r10d,r8d
jae 00007FFB17DB6D5F
mov r11,rcx ; <-- Unexpected - Extra register copy?
movups xmm0,xmmword ptr [r11+rax*4+10h ]
;// Vector<float> vb = new Vector<float>(b, i);
cmp eax,r9d ; <-- Unexpected - Compare b.Length to i?
jae 00007FFB17DB6D5F ; <-- Unexpected - Jump to range check failure
cmp r10d,r9d
jae 00007FFB17DB6D5F
movups xmm1,xmmword ptr [rdx+rax*4+10h]
ループ範囲チェックが期待どおりであることに注意してください。
;// for (i = 0; i < a.Length - simdLength; i += simdLength) {
add eax,4
cmp r9d,eax
jg loop
との追加の比較がある理由がわかりませんeax
。これらの余分な指示が表示される理由と、それらを取り除くことが可能かどうかを誰かが説明できますか?
プロジェクト設定に関連している場合は、 github で同じ問題を示す非常によく似たプロジェクトがあります(FloatSimdProcessor.HwAcceleratedSumInPlace()
またはを参照UShortSimdProcessor.HwAcceleratedSumInPlaceUnchecked()
)。