我开发的软件使用的是大的浮点数组,最大的大小可以在C#中分配。我有很多算法,比如卷积和过滤器,这些算法可以在这些大型数组上执行。我目前正在更新尽可能多的算法,以实现完全线程化和矢量化。
通过使用System.Numerics.Vector<T>方法,我看到了在配备AVX的计算机上的许多算法( Vector<float>.Count返回4)上的300%+性能改进,以及在配备AVX2 ( Vector<float>.Count返回8)的计算机上的许多算法中的600%+性能改进。
NET标准2.1 System.Numerics.Vector<T>:
https://docs.microsoft.com/en-us/dotnet/api/system.numerics.vector-1?view=netstandard-2.1
我在许多算法上需要的函数之一是,在对数组元素值执行一些数学操作之后,将其夹紧到一个界、最小值或最大值。当然,对于使用标准算术操作的单线程和多线程算法来说,这是非常容易的。
我遇到的问题是,System.Numerics.Vector<T>不包括任何类型的钳位方法(Vector2,3,4 do)。因此,例如,如果我在一个大数组上循环,修改Vector<float>.Count块中的数组,那么在将向量大小的块写入数组之前,我需要将每个向量结果夹紧到一个min和/或最大界。
在向量操作之后,我尝试在数组块数据上做循环中的线夹,但是性能很差。它比简单的没有矢量化的算法慢或慢。
有什么办法可以想象我可以提高这种夹紧方法的性能吗?
这是一些典型的代码,我如何尝试夹紧。我用数组中的一个块填充向量,执行一些向量运算,将块写回数组,这一切都很好,而且速度很快,但是在扼杀了向量化性能优势之后,我在循环中夹紧数组块。
int length = array.Length;
int floatcount = System.Numerics.Vector<float>.Count;
for (int i = 0; i < length; i += floatcount)
{
System.Numerics.Vector<float> arrayvector = new System.Numerics.Vector<float>(array, i);
arrayvector = System.Numerics.Vector.Multiply<float>(arrayvector, 2.0f);
// There may be different or multiple vector operations in here.
arrayvector.CopyTo(array, i);
// This is how I tried clamping the array data after the vector operation:
for (int j = 0; j < floatcount; j++)
{
if (array[i + j] > maximimum) { array[i + j] = maximimum; }
}
}我可能是近视而错过了一些很简单的东西。这就是几个月的16小时编程日带给你的好处。)谢谢你的见解。
发布于 2019-05-10 08:41:45
你试过这样的方法吗?
创建以下向量:
System.Numerics.Vector<float> maxima = new System.Numerics.Vector<float>(maximimum);然后在乘法调用之后:
arrayvector = System.Numerics.Vector.Min(arrayvector, maxima);在这里,您可能必须创建一个新的向量,而不是重新分配到数组向量?
总之,最终结果是:
int length = array.Length;
int floatcount = System.Numerics.Vector<float>.Count;
System.Numerics.Vector<float> maxima = new System.Numerics.Vector<float>(maximimum);
for (int i = 0; i < length; i += floatcount)
{
System.Numerics.Vector<float> arrayvector = new System.Numerics.Vector<float>(array, i);
arrayvector = System.Numerics.Vector.Multiply(arrayvector, 2.0f);
arrayvector = System.Numerics.Vector.Min(arrayvector, maxima);
// There may be different or multiple vector operations in here.
arrayvector.CopyTo(array, i);
}免责声明:我还没有测试过上面的内容,所以如果这不是一个改进,就不要挂我:-)
https://codereview.stackexchange.com/questions/220035
复制相似问题