RyuJIT没有充分利用SIMD指令集优化

15

我正在运行一些使用 System.Numerics.Vector<T> 的 C# 代码,但据我所知,我没有充分利用 SIMD intrinsics。我使用带有更新1的Visual Studio Community 2015,并且我的clrjit.dll是v4.6.1063.1。

我正在运行的是搭载AVX指令集扩展的Intel Core i5-3337U处理器。因此,我认为我应该能够在256位寄存器上执行大多数SIMD指令。例如,反汇编应该包含像vmovupsvmovupdvaddups等指令,而Vector<float>.Count应该返回8,Vector<double>.Count应该返回4,等等...但这不是我所看到的。

相反,我的反汇编包含像movupsmovupdaddups等指令,以及以下代码:

WriteLine($"{Vector<byte>.Count} bytes per operation");
WriteLine($"{Vector<float>.Count} floats per operation");
WriteLine($"{Vector<int>.Count} ints per operation");
WriteLine($"{Vector<double>.Count} doubles per operation");

产生:

16 bytes per operation
4 floats per operation
4 ints per operation
2 doubles per operation

我错在哪里?要查看所有项目设置等内容,请前往此处查看项目。


1
RyuJIT在GitHub上是开源的,因此您可以查看其代码并直接与开发人员讨论。 - Lex Li
1个回答

12

您的处理器有些过时,其微架构是Ivy Bridge。 Sandy Bridge的“tock”是一种缩小特征而没有架构变化的方法。 您的劲敌是RyuJIT中的此代码段,在ee_il_dll.cpp中,CILJit :: getMaxIntrinsicSIMDVectorLength()函数:链接

if (((cpuCompileFlags & CORJIT_FLG_PREJIT) == 0) &&
    ((cpuCompileFlags & CORJIT_FLG_FEATURE_SIMD) != 0) &&
    ((cpuCompileFlags & CORJIT_FLG_USE_AVX2) != 0))
{
    static ConfigDWORD fEnableAVX;
    if (fEnableAVX.val(CLRConfig::EXTERNAL_EnableAVX) != 0)
    {
        return 32;
    }
}

请注意使用CORJIT_FLG_USE_AVX2标记。您的处理器尚不支持AVX2,该扩展在Haswell中提供。这是Ivy Bridge后的下一代微架构“tick”。顺便说一句,它是非常好的处理器,像这个发现具有重大的惊叹效果。

对于此问题,您无能为力,只能去购物了。如果需要灵感,可以查看此帖子中生成的代码类型。


他实际上也可以尝试实现AVX支持并提交补丁。不过这并不是一个现实的选择。或者在那里开一个工单——也许使用AVX2并非完全有意?但总的来说——是的。购物是最好的选择。 - TomTom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接