【问题标题】:RyuJIT not making full use of SIMD intrinsicsRyuJIT 没有充分利用 SIMD 内在函数
【发布时间】:2016-04-26 03:06:56
【问题描述】:

我正在运行一些使用 System.Numerics.Vector<T> 的 C# 代码,但据我所知,我没有获得 SIMD 内在函数的全部好处。我正在使用带有 Update 1 的 Visual Studio Community 2015,我的 clrjit.dll 是 v4.6.1063.1。

我在 Intel Core i5-3337U Processor 上运行,它实现了 AVX 指令集扩展。因此,我认为,我应该能够在 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

我哪里出错了?要查看所有项目设置等。项目可用here

【问题讨论】:

  • RyuJIT 在 GitHub 上是开源的,因此您可以查看它的代码并直接与开发人员讨论。

标签: c# sse simd avx ryujit


【解决方案1】:

你的处理器有点过时了,它的微架构是 Ivy Bridge。 Sandy Bridge 的“tock”,在没有建筑变化的情况下缩小了特征。你的克星是 RyuJIT 中的这段代码,located in 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”。顺便说一句,非常好的处理器,像this one 这样的发现有一个主要的令人惊叹的因素。

除了购物之外,您无能为力。如需灵感,您可以查看它在 this post 中生成的代码。

【讨论】:

  • 他其实也可以尝试实现AVX支持并提交补丁。并不是说这是一个现实的选择。或者在那里开一张票——也许使用 AVX2 不是完全故意的?但通常 - 是的。购物是最好的选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-30
  • 2012-12-15
  • 2020-12-26
  • 2015-11-11
  • 1970-01-01
  • 2012-01-11
相关资源
最近更新 更多