首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C# System.Numerics.Vector<T>钳

C# System.Numerics.Vector<T>钳
EN

Code Review用户
提问于 2019-05-10 06:36:08
回答 1查看 1.1K关注 0票数 4

我开发的软件使用的是大的浮点数组,最大的大小可以在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和/或最大界。

在向量操作之后,我尝试在数组块数据上做循环中的线夹,但是性能很差。它比简单的没有矢量化的算法慢或慢。

有什么办法可以想象我可以提高这种夹紧方法的性能吗?

这是一些典型的代码,我如何尝试夹紧。我用数组中的一个块填充向量,执行一些向量运算,将块写回数组,这一切都很好,而且速度很快,但是在扼杀了向量化性能优势之后,我在循环中夹紧数组块。

代码语言:javascript
复制
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小时编程日带给你的好处。)谢谢你的见解。

EN

回答 1

Code Review用户

回答已采纳

发布于 2019-05-10 08:41:45

你试过这样的方法吗?

创建以下向量:

代码语言:javascript
复制
  System.Numerics.Vector<float> maxima = new System.Numerics.Vector<float>(maximimum);

然后在乘法调用之后:

代码语言:javascript
复制
arrayvector = System.Numerics.Vector.Min(arrayvector, maxima);

在这里,您可能必须创建一个新的向量,而不是重新分配到数组向量?

总之,最终结果是:

代码语言:javascript
复制
  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);

  }

免责声明:我还没有测试过上面的内容,所以如果这不是一个改进,就不要挂我:-)

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/220035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档