.net core SIMD范例分析

Posted fancybit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.net core SIMD范例分析相关的知识,希望对你有一定的参考价值。

单指令多数据流(SIMD)是CPU基本运算之外为了提高并行处理多条数据效率的技术,常用于多媒体处理如视频,3D模拟的计算。实现方式不同品牌的CPU各有自己的指令集,如SSE MMX 3DNOW等。

C#开发.net core软件的过程中也可以让编译器自动采用这些SIMD指令集进行代码优化,测试了一下在我的AMD 锐龙7 2700X上对于整数加法处理可以提高10倍的效率。

下面是我自己写的例子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;

namespace MySIMDTest

    class Program
    
        static Random rand = new Random();
        static Vector<int> getVec32(int count)
        
            var lst = new List<int>(count);
            for (int i = 0; i < count; ++i) lst.Add(rand.Next(100));
            return new Vector<int>(lst.ToArray());
        

        static Vector<short> getVec16(int count)
        
            var lst = new List<int>(count);
            for (int i = 0; i < count; ++i) lst.Add(rand.Next(100));
            return new Vector<short>(lst.Select(i => (short)i).ToArray());
        

        static void Main(string[] args)
        
            var sw = new Stopwatch();
            var testTimes = (int)(Math.Pow(10, 5));
            var vecSize = (int)(Math.Pow(10, 2));

            Action testNormal = () =>
            
                Console.Write("normal test ");
                var lstVecN1 = new List<Vector<int>>();
                var lstVecN2 = new List<Vector<int>>();
                for (int i = 0; i < testTimes; ++i)
                
                    lstVecN1.Add(getVec32(vecSize));
                    lstVecN2.Add(getVec32(vecSize));
                

                sw.Restart();
                for (int i = 0; i < testTimes; ++i)
                
                    for(int j = 0; j < vecSize; ++j)
                    
                        var r = lstVecN1[i] + lstVecN2[i];
                    
                
                sw.Stop();
                Console.WriteLine(sw.Elapsed);
            ;

            Action test16 = () =>
            
                Console.Write("16 test");
                var lstVecA1 = new List<Vector<short>>();
                var lstVecA2 = new List<Vector<short>>();
                for (int i = 0; i < testTimes; ++i)
                
                    lstVecA1.Add(getVec16(vecSize));
                    lstVecA2.Add(getVec16(vecSize));
                

                sw.Restart();
                for (int i = 0; i < testTimes; ++i)
                
                    var result1 = lstVecA1[i] + lstVecA2[i];
                
                sw.Stop();
                Console.WriteLine(sw.Elapsed);
            ;


            Action test32 = () =>
            
                Console.Write("32 test");
                var lstVecB1 = new List<Vector<int>>();
                var lstVecB2 = new List<Vector<int>>();
                for (int i = 0; i < testTimes; ++i)
                
                    lstVecB1.Add(getVec32(vecSize));
                    lstVecB2.Add(getVec32(vecSize));
                

                sw.Restart();
                for (int i = 0; i < testTimes; ++i)
                
                    var result1 = lstVecB1[i] + lstVecB2[i];
                
                sw.Stop();
                Console.WriteLine(sw.Elapsed);
            ;

            for (int i = 0; i < 8; ++i) testNormal();
            for (int i = 0; i < 8; ++i) test32();
            for (int i = 0; i < 8; ++i) test16();
            Console.ReadKey();
        
    
技术图片

运行结果:

技术图片技术图片?

只要用Vector<T>支持的重载运算符来代替数组或者列表之类进行计算,即可获得编译器SIMD自动优化指令的效果。不过目前文档里说只支持x86系列的CPU ARM的CPU相关支持还在研发中

以上是关于.net core SIMD范例分析的主要内容,如果未能解决你的问题,请参考以下文章

流分析服务和 WebApp 服务之间的数据流 (.NET core 3.1)

.net core SignalR 在线压力测试结果分析

.NET Core 3.1 项目的 SonarQube 分析失败

ASP.NET CORE MVC用时分析工具MiniProfiler

应用工具 .NET Portability Analyzer 分析迁移dotnet core

.NET Core分析程序集最优美的方法,不用Assembly.LoadFile(),超越ReflectionOnlyLoad