我正在测试通过 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()
)。