【发布时间】:2021-01-04 16:03:22
【问题描述】:
我正在编写一个 SIMD 库,并试图充分发挥性能。
我已经将array 就地转换为Span<Vector<int>>,而不是创建新对象。
目标数组很大(超过 1000 个元素)。
有没有更有效的方法对数组求和?
欢迎提出想法。
public static int Sum(int[] array)
{
Vector<int> vSum = Vector<T>.Zero;
int sum;
int i;
Span<Vector<int>> vsArray = MemoryMarshal.Cast<int, Vector<int>>(array);
for (i = 0; i < vsArray.Length; i++)
{
vSum += vsArray[i];
}
sum = Vector.Dot(vSum, Vector<int>.One);
i *= Vector<int>.Count;
for (; i < array.Length; i++)
{
sum += array[i];
}
return sum;
}
【问题讨论】:
-
除非 C# 使用
1优化点积中的乘法,否则效率不高。它在循环之外,所以它非常小,但仍然无缘无故地需要一个向量常数。 Fastest way to do horizontal SSE vector sum (or other reduction) 展示了 C intriniscs 的有效水平求和。 -
除此之外,这是相当合理的。如果 C# 不为您执行此操作(使用多个矢量累加器)以隐藏延迟并允许吞吐量为 2 个矢量加载 + 如果数据在缓存中很热,则每个时钟添加的吞吐量可能需要手动展开循环。但是我没有 C# 开发设置来查看您实际上从中得到了什么。
-
看看youtube.com/watch?v=mFZIj2y3Le0。也许有帮助。
-
另外,这里是habr.com/en/post/467689
标签: c# performance simd