在c#中,用常量乘/加一个大数组的高性能方法是什么?

本文关键字:数组 一个 高性能 是什么 方法 常量 | 更新日期: 2023-09-27 18:02:20

我有一个结构(类),它在数组中保存了大量的数字(float, double, int, byte)。

现在我想有一个非常高性能的方法来应用一些基本操作(加/减/除/乘常数)在这个数组上。

这个数组是在一个连续的内存块上,所以例如复制它,我使用Buffer.BlockCopy.

但是加一个常数或者乘以一个常数呢?

第一种选择是使用指针遍历数组。对此你有什么其他的建议吗?

在c#中,用常量乘/加一个大数组的高性能方法是什么?

使用指针(不安全)并不一定会提高性能。

你为什么不从一个正常的for(int index = 0; index < data.Lenght; index++)循环开始,看看它是否符合你的要求。


当然,下一步是并行处理:

 Parallel.For(0, data.Length, i => data[i] *= myFactor);

指针帮不上什么忙。可以/应该结合的两种方法:

  • 使用某种SIMD方法并行处理多个数字,SSE是它的一个实例
  • 在不同线程中处理不同的数组块("多线程");这在CPU核数大于
  • 的机器上是最值得的。

如果你想减少("减少")结果,例如说你想构建所有元素的总和,你也可以递归地划分块,并构建总和的总和(总和的总和(总和的总和))

将每个元素与5相乘,并写回同一个数组。

        var someArray = new int[] {1, 2, 3, 4, 5, 6, 7};
        int i=0;
        Array.ForEach(someArray, (x) => {someArray[i++] = x * 5;});

我不认为你会找到一个通用的解决方案比只是遍历数组更快。大多数处理器会预取数组中的项;因此,只要您的操作很小,您就可以通过连续访问每个项来获得最佳性能。

保持每个项目的工作尽可能简单,并尽量减少循环内的分配和获取。在循环之外保持尽可能多的工作