.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相关支持还在研发中

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

时间: 2024-10-24 13:31:34

.net core SIMD范例分析的相关文章

spark core源码分析6 Spark job的提交

本节主要讲解SparkContext的逻辑 首先看一个spark自带的最简单的例子: object SparkPi { def main(args: Array[String]) { val conf = new SparkConf().setAppName("Spark Pi") val spark = new SparkContext(conf) val slices = if (args.length > 0) args(0).toInt else 2 val n = ma

DOTNET CORE源码分析之IOC容器结果获取内容补充

补充一下ServiceProvider的内容 可能上一篇文章DOTNET CORE源码分析之IServiceProvider.ServiceProvider.IServiceProviderEngine.ServiceProviderEngine和ServiceProviderEngineScope 中还没有关联上ServiceProvider和ServiceCollection就直接通过GetService获取了值,这样不科学啊.其实是有关联的,请看一下上篇文章同样存在的一个代码段: inte

spark core源码分析7 Executor的运行

实际任务的运行,都是通过Executor类来执行的.这一节,我们只介绍Standalone模式. 源码位置:org.apache.spark.executor.CoarseGrainedExecutorBackend private def run( driverUrl: String, executorId: String, hostname: String, cores: Int, appId: String, workerUrl: Option[String], userClassPath

spark core源码分析8 从简单例子看transformation

前面提到过spark自带的一个最简单的例子,也介绍了SparkContext的部分,这节介绍剩余的内容中的transformation. object SparkPi { def main(args: Array[String]) { val conf = new SparkConf().setAppName("Spark Pi") val spark = new SparkContext(conf) val slices = if (args.length > 0) args(

CORE网络仿真软件分析

CORE采用LXC(Linux namespace Container)技术和Bridge技术实现虚拟主机和虚拟网络的仿真模拟.LXC利用cgroups子系统中的进程组资源管理框架将虚拟主机实现为同一个组相对独立的进程.LXC已加入到内核2.6.28版本,CORE对虚拟主机创建和管理,通过的C语言系统调用来的实现,具体代码实现在core/daemon/src文件夹下. 文件列表 文件名称 功能说明 vnoded_main.c 创建LXC容器运行的守护进程vnoded(PID 1) vcmd_ma

spark core源码分析13 异常情况下的容错保证

博客地址: http://blog.csdn.net/yueqian_zhu/ standalone模式下的框架图如下: 异常分析1: worker异常退出 worker异常退出,比如说有意识的通过kill指令将worker杀死 worker在退出之前,会将自己所管控的所有小弟executor全干掉 worker需要定期向master改善心跳消息的,现在worker进程都已经玩完了,哪有心跳消息,所以Master会在超时处理中意识到有一个"分舵"离开了 Master非常伤心,伤心的Ma

spark core源码分析14 参数配置

博客地址: http://blog.csdn.net/yueqian_zhu/ spark 参数详解 一.Shuffle 相关 1.spark.shuffle.manager(默认 sort) HashShuffleManager,故名思义也就是在Shuffle的过程中写数据时不做排序操作,只是将数据根据Hash的结果,将各个Reduce分区的数据写到各自的磁盘文件中.带来的问题就是如果Reduce分区的数量比较大的话,将会产生大量的磁盘文件.如果文件数量特别巨大,对文件读写的性能会带来比较大的

spark core源码分析10 Task的运行

这一节介绍具体task的运行以及最终结果的处理 看线程运行的run方法,见代码注释 override def run(): Unit = { val taskMemoryManager = new TaskMemoryManager(env.executorMemoryManager) val deserializeStartTime = System.currentTimeMillis() Thread.currentThread.setContextClassLoader(replClass

spark core源码分析9 从简单例子看action操作

上一节举例讲解了transformation操作,这一节以reduce为例讲解action操作 首先看submitJob方法,它将我们reduce中写的处理函数随JobSubmitted消息传递出去,因为每个分区都需要调用它进行计算: 而resultHandler是指最后合并的方法,在每个task完成后,需要调用resultHandler将最终结果合并.所以它不需要随JobSubmitted消息传递,而是保存在JobWaiter中 /** * Submit a job to the job sc