经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » ASP.net » 查看文章
【一天一点.NET小知识】运用向量Vector<T>加速求和计算
来源:cnblogs  作者:VAllen  时间:2024/7/11 11:12:41  对本文有异议

随着 .NET 版本的演进,从 .NET Standard 2.0 版本开始,支持 Vector<T> 类型。
.NET 8.0 版本开始,大量在 Runtime 提供的各个组件中运用向量计算,?特别是 Linq。
Vector 类型:表示指定数值类型(适用于并行算法的低级别优化)的单个向量。

假如我们有一个求和函数接受一个int数组入参,当它的长度大于等于8及其倍数以上时,那么我们就可以考虑使用向量Vector<T>加速求和计算。

以下是使用了向量的求和函数代码:

  1. internal class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. int[] array = Enumerable.Range(1, 32).ToArray();
  6. int result = Sum(array);
  7. Console.WriteLine(result);
  8. Console.ReadKey();
  9. }
  10. public static int Sum(int[] numbers)
  11. {
  12. ReadOnlySpan<int> span = new ReadOnlySpan<int>(numbers);
  13. ref int ptr = ref MemoryMarshal.GetReference(span);
  14. int result = 0;
  15. int vectorSize = Vector<int>.Count;
  16. int index;
  17. int remainder = span.Length % vectorSize;
  18. int vectorLength = span.Length - remainder;
  19. Vector<int> vector = Vector<int>.Zero;
  20. for (index = 0; index < vectorLength; index += vectorSize)
  21. {
  22. //Vector<int> vector2 = new Vector<int>(span.Slice(index, vectorSize));
  23. ref byte address = ref Unsafe.As<int, byte>(ref Unsafe.Add(ref Unsafe.AsRef(in ptr), index));
  24. Vector<int> vector2 = Unsafe.ReadUnaligned<Vector<int>>(ref address);
  25. vector += vector2;
  26. }
  27. result += Vector.Dot<int>(vector, Vector<int>.One);
  28. for (; index < span.Length; index++)
  29. {
  30. result += Unsafe.Add(ref ptr, index);
  31. }
  32. return result;
  33. }
  34. }

以下是相减函数代码:

  1. static int Sub(int[] numbers)
  2. {
  3. ReadOnlySpan<int> span = new ReadOnlySpan<int>(numbers);
  4. ref int ptr = ref MemoryMarshal.GetReference(span);
  5. int result = 0;
  6. int vectorSize = Vector<int>.Count;
  7. int index;
  8. int remainder = span.Length % vectorSize;
  9. int vectorLength = span.Length - remainder;
  10. for (index = 0; index < vectorLength; index += vectorSize)
  11. {
  12. ref byte address = ref Unsafe.As<int, byte>(ref Unsafe.Add(ref Unsafe.AsRef(in ptr), index));
  13. Vector<int> vector = Unsafe.ReadUnaligned<Vector<int>>(ref address);
  14. result -= Vector.Dot<int>(vector, Vector<int>.One);
  15. }
  16. for (; index < span.Length; index++)
  17. {
  18. result -= Unsafe.Add(ref ptr, index);
  19. }
  20. return result + 2;
  21. }

其它运算,例如相减,也是同理。
以上代码,均可以在 .NET Standard 2.0 及以上版本运行。

当我们向量 Vector<T> 之后,特别是在一些频繁调用计算的场景,将获得指数量级的性能提升。
需要注意的是,向量 Vector<T> 依赖 CPU 硬件的 SIMD 指令集支持,在一些相对较旧的 古董CPU,可能不支持。

PS:

原文链接:https://www.cnblogs.com/VAllen/p/18293030/accelerate-summation-calculations-using-vector

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号