如何在新的 .NET Framework 4.6 中启用 SIMD?

Posted

技术标签:

【中文标题】如何在新的 .NET Framework 4.6 中启用 SIMD?【英文标题】:How to enable SIMD in a new .NET Framework 4.6? 【发布时间】:2015-08-09 16:13:40 【问题描述】:

我写了一个代码来测试,哪种方式更快。我在 Release x64 中运行代码。我有 .NET Framework 4.6 的 VS 2015 Pro。

#if SYSTEMMATHLIB
using System.Numerics;
#else
using Engine.Mathematic;
#endif

namespace Engine.Editor

    public static class Program
    
        public static void Main()
        
            #if SYSTEMMATHLIB
            Console.WriteLine("Hardware Acceleration: " + Vector.IsHardwareAccelerated.ToString());
            #endif

            Stopwatch sw = new Stopwatch();
            sw.Start();

#if SYSTEMMATHLIB
            for (int i = 0; i < 1000000; i++)
            
                Matrix4x4 m = Matrix4x4.CreateRotationZ(0.50f);
                m.Translation = new Vector3(5, 10, 15);

                Matrix4x4 m2 = Matrix4x4.CreateRotationX(0.50f);
                m2.Translation = new Vector3(-5, 10, -15);

                Matrix4x4 m3 = m * m2;
                Matrix4x4 inv; Matrix4x4.Invert(m3, out inv);
            
#else
            for (int i = 0; i < 1000000; i++)
            
                Matrix m = Matrix.RotationZ(0.50f);
                m.TranslationVector = new Vector3(5, 10, 15);

                Matrix m2 = Matrix.RotationX(0.50f);
                m2.TranslationVector = new Vector3(-5, 10, -15);

                Matrix m3 = m * m2;
                Matrix inv; Matrix.Invert(ref m3, out inv);
            
#endif
            long mili = sw.ElapsedMilliseconds;
            sw.Stop();        

            Console.WriteLine("Total mili: " + mili.ToString());
            Console.ReadLine();
        
    

好吧,如果我使用 Framework 4.6(Nuget 版本)中的 System.Numerics 运行它,计算需要 212 毫秒。如果我将它切换到我的库,这只是简单的 c# 代码来计算它,它也需要大约 210 毫秒。这有点奇怪吧?我虽然 SIMD 应该更快!

顺便说一下,IsHardwareAccelerated 返回“True”。

所以我做错了什么???

仅供参考:没有 SIMD 的 C++ 运行时间为 390 毫秒,使用 SIMD 的时间为 77 毫秒。

【问题讨论】:

我对 .NET 对 SIMD 的使用一无所知,但要使 SIMD 指令真正有用,需要有机会对多组数据并行执行相同的操作.我在您的代码中看不到这样的机会。特别是所有输入和输出都在循环体内创建。 这不是典型的用例。可能是创建矩阵的行为尚未构建为使用 SIMD。通常,一次将单个矩阵变换应用于多个向量。 好吧,这里也一样。我在 C++ 中编写了相同的代码,结果非常不同,因此使用 SSE2 比自己在 C 代码中计算要快得多。 Cory Nelsen:我也在做矩阵乘法和矩阵求逆,而不仅仅是创建。 您没有使用 .NET 4.6 版本,无法再访问 Version.IsHardwareAccelerated。没有真正的区别,SIMD 支持与 CTP 版本相比没有实质性变化。只有 Vector2/3/4 得到了 [JitIntrinsic] 的喜爱。不是 Matrix4x4。也许下一个版本。 Backgrounder post 仍然准确。 【参考方案1】:

我反编译了 System.Numerics.Vector 并意识到,SIMD 仅适用于 Vector,而不适用于 Matrix4x4。所以 Hans Passant 是对的。

我希望他们也能尽快添加对 SIMD Matrix 的支持。

【讨论】:

以上是关于如何在新的 .NET Framework 4.6 中启用 SIMD?的主要内容,如果未能解决你的问题,请参考以下文章

已安装 4.6 时如何满足 .Net Framework 4.0 要求

win10 怎么安装.net framework 4.6

.net framework 4.6 无法安装

从 .NET Framework 4.6 迁移到 .NET5 后,API 帖子正文为空

在 .NET Framework 4.6 中使用 C# 的 SIMD 操作速度较慢

发布在 C# .net framework 4.6 中开发的 Web API 的命令 [重复]