将一天一点.NET小知识运用到向量(Vector)的概念中,可以理解为将.NET编程中的某个知识点以向量化的方式呈现,即以一个有方向和大小(重要性)的知识点来表示。以下是一个比喻性的例子:假设一天一点.NET小知识是一个向量,我们可以这样描述:- **方向

摘要:随着 .NET 版本的演进,从 .NET Standard 2.0 版本开始,支持 Vector<T> 类型。 从 .NET 8.0 版本开始,大量在 Runtime 提供的各个组件中运用向量计算
随着 .NET 版本的演进,从 .NET Standard 2.0 版本开始,支持 Vector<T> 类型。 从 .NET 8.0 版本开始,大量在 Runtime 提供的各个组件中运用向量计算,​特别是 Linq。 Vector 类型:表示指定数值类型(适用于并行算法的低级别优化)的单个向量。 假如我们有一个求和函数接受一个int数组入参,当它的长度大于等于8及其倍数以上时,那么我们就可以考虑使用向量Vector<T>加速求和计算。 以下是使用了向量的求和函数代码: internal class Program { static void Main(string[] args) { int[] array = Enumerable.Range(1, 32).ToArray(); int result = Sum(array); Console.WriteLine(result); Console.ReadKey(); } public static int Sum(int[] numbers) { ReadOnlySpan<int> span = new ReadOnlySpan<int>(numbers); ref int ptr = ref MemoryMarshal.GetReference(span); int result = 0; int vectorSize = Vector<int>.Count; int index; int remainder = span.Length % vectorSize; int vectorLength = span.Length - remainder; Vector<int> vector = Vector<int>.Zero; for (index = 0; index < vectorLength; index += vectorSize) { //Vector<int> vector2 = new Vector<int>(span.Slice(index, vectorSize)); ref byte address = ref Unsafe.As<int, byte>(ref Unsafe.Add(ref Unsafe.AsRef(in ptr), index)); Vector<int> vector2 = Unsafe.ReadUnaligned<Vector<int>>(ref address); vector += vector2; } result += Vector.Dot<int>(vector, Vector<int>.One); for (; index < span.Length; index++) { result += Unsafe.Add(ref ptr, index); } return result; } } 以下是相减函数代码: static int Sub(int[] numbers) { ReadOnlySpan<int> span = new ReadOnlySpan<int>(numbers); ref int ptr = ref MemoryMarshal.GetReference(span); int result = 0; int vectorSize = Vector<int>.Count; int index; int remainder = span.Length % vectorSize; int vectorLength = span.Length - remainder; for (index = 0; index < vectorLength; index += vectorSize) { ref byte address = ref Unsafe.As<int, byte>(ref Unsafe.Add(ref Unsafe.AsRef(in ptr), index)); Vector<int> vector = Unsafe.ReadUnaligned<Vector<int>>(ref address); result -= Vector.Dot<int>(vector, Vector<int>.One); } for (; index < span.Length; index++) { result -= Unsafe.Add(ref ptr, index); } return result + 2; } 其它运算,例如相减,也是同理。 以上代码,均可以在 .NET Standard 2.0 及以上版本运行。 当我们向量 Vector<T> 之后,特别是在一些频繁调用计算的场景,将获得指数量级的性能提升。 需要注意的是,向量 Vector<T> 依赖 CPU 硬件的 SIMD 指令集支持,在一些相对较旧的 古董CPU,可能不支持。 PS: uint类型数组:长度大于等于8及其倍数以上 long类型数组:长度大于等于4及其倍数以上 ulong类型数组:长度大于等于4及其倍数以上 SIMD:Single Instruction, Multiple Data,单指令多数据流 Vector介绍:https://learn.microsoft.com/zh-cn/dotnet/api/system.numerics.vector-1