.net core SIMD範例分析

單指令多數據流(SIMD)是CPU基本運算以外爲了提升並行處理多條數據效率的技術,經常使用於多媒體處理如視頻,3D模擬的計算。實現方式不一樣品牌的CPU各有本身的指令集,如SSE MMX 3DNOW等。數組

C#開發.net core軟件的過程當中也能夠讓編譯器自動採用這些SIMD指令集進行代碼優化,測試了一下在個人AMD 銳龍7 2700X上對於整數加法處理能夠提升10倍的效率。app

下面是我本身寫的例子:dom

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相關支持還在研發中優化

相關文章
相關標籤/搜索