C# 向量化数组加法

12
有没有办法以SIMD方式“向量化”数组之间的元素相加?
例如,我想将以下操作进行向量化:
var a = new[] { 1, 2, 3, 4 };
var b = new[] { 1, 2, 3, 4 };
var c = new[] { 1, 2, 3, 4 };
var d = new[] { 1, 2, 3, 4 };

var e = new int[4];

for (int i = 0; i < a.Length; i++)
{
    e[i] = a[i] + b[i] + c[i] + d[i];
}

// e should equal { 4, 8, 12, 16 }

转化为类似于:

var e = VectorAdd(a,b,c,d);

我知道在C++ / XNA库中可能存在某些东西,但是我不知道我们是否在标准的.Net库中有它。

谢谢!


我认为像你写的这样简单的循环会被优化编译器向量化。 - Tudor
3个回答

14

你需要查看 Mono.Simd:

http://tirania.org/blog/archive/2008/Nov-03.html

它支持在 C# 中使用 SIMD。

using Mono.Simd;


//...
var a = new Vector4f( 1, 2, 3, 4 );
var b = new Vector4f( 1, 2, 3, 4 );
var c = new Vector4f( 1, 2, 3, 4 );
var d = new Vector4f( 1, 2, 3, 4 );

var e = a+b+c+d;

请注意,您可以使用汇编语言,但仅当它在支持SIMD指令的mono CLR中运行时才会使用它们。 - redcalx

5
Mono提供了一个相对不错的SIMD API(正如sehe所提到的),但如果Mono不是一个选项,我可能会编写一个C++/CLI接口库来完成繁重的工作。C#对于大多数问题集合来说效果还不错,但如果你开始进入高性能代码领域,最好选择一种语言,让你有控制权,真正深入性能优化。
在我们这里,我们使用P/Invoke从C#调用用C++编写的图像处理例程。P/Invoke有一些开销,但如果你做很少的调用,并在本地端进行大量的处理,它可以值得尝试。

2
我想这完全取决于您要做什么,但如果您担心矢量化矢量总和,您可能需要查看诸如Math.NET之类的库,它提供了优化的数值计算。
从他们的网站上可以看到:
它针对Microsoft .Net 4.0、Mono和Silverlight 4,并且除了纯管理实现外,还支持本地硬件优化(MKL、ATLAS)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接