码迷,mamicode.com
首页 > Web开发 > 详细

.net core SIMD范例分析

时间:2019-08-26 15:20:22      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:处理   品牌   img   image   oar   read   for   -o   god   

单指令多数据流(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范例分析

标签:处理   品牌   img   image   oar   read   for   -o   god   

原文地址:https://www.cnblogs.com/fancybit/p/11412198.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!