【问题标题】:Fastest way to sum array of float values [duplicate]对浮点值数组求和的最快方法[重复]
【发布时间】:2021-06-01 05:33:25
【问题描述】:

我使用 Visual Studio 和 C++ 进行 DSP 编码。

我有一个浮点数组,现在只有 8 个,但以后可能会更改为或多或少,我需要对单个浮点变量求和,然后取平均值。

我想使用内在指令,我没有经验以及为什么在这里问。

所需要的只是代码比我在下面得到的要快,并且它将在过去 5 年内在 Intel 和 AMD 处理器上运行。

注意所有数组的float值都在-1和1之间,速度比精度更重要。

float sum = (sampleValue[0] + sampleValue[1] + sampleValue[2] + sampleValue[3] +
             sampleValue[4] + sampleValue[5] + sampleValue[6] + sampleValue[7]) / 8;

如果这个问题已经得到解答,我深表歉意,如果是,请指导我回答,谢谢。

另外,如果有人可以指导我阅读“傻瓜的内在函数”在线文章/教程,我将不胜感激,谢谢!

【问题讨论】:

  • 我会使用std::reduce。它可能是使用 CPU 中可用的快速指令以一种有效的方式实现的。
  • std::reduce 在我的编译器中似乎不可用,尽管 std::accumulate 可用。不过我不太确定如何使用它。
  • @ravenspoint 这不是最理想的,因为它包含两个间接级别。将数据存储在单个 std::vector<float> 中并计算适当的偏移量应该会更快,因为它对缓存更友好。
  • @DKDiveDude: std::accumulate 将适用于任何迭代器对,并且指针也是迭代器。无需从float[]更改。
  • @pptaszni:你通常想使用0.0f,而不是0.0,所以累积类型是float而不是double,不强制编译器将float转换为double苍蝇。但是要让编译器矢量化(从 addps 开始以减少 8 到 4 个元素),您需要一个“快速数学”选项或授予它对该特定循环的权限。

标签: c++ visual-studio intel intrinsics amd-processor


【解决方案1】:

我假设您正在考虑 SIMD(单指令多数据)操作。

搜索“SIMD 内在函数”将为您提供大量资源,但这里有一个不错的入门资源:https://stackoverflow.blog/2020/07/08/improving-performance-with-simd-intrinsics-in-three-use-cases/

这篇文章也更接近您的用例: http://blog.zachbjornson.com/2019/08/11/fast-float-summation.html

【讨论】:

    【解决方案2】:

    建议使用指针

    float sum = 0;
    float* p = sampleValue;
    for( int k = 0; k< 8; k++ )
        sum += *p++;
    

    【讨论】:

    • 感谢您的加入,但是没有可以对整个数组求和的内在向量类型函数吗?
    • 在幕后,任何此类函数都可能使用此代码,但会产生函数调用的开销——可能编译器已优化掉。
    • 在执行此操作的循环内测试并计算了高分辨率滴答声。我自己的简单版本快了 9%。
    猜你喜欢
    • 1970-01-01
    • 2021-02-19
    • 2015-02-20
    • 1970-01-01
    • 2019-03-13
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 2020-03-24
    相关资源
    最近更新 更多