【问题标题】:Performance optimization for indexed sum索引和的性能优化
【发布时间】:2018-05-02 23:01:44
【问题描述】:

给定一个浮点数组,以及另一个将值索引到应该求和的数组中的排序数组——有没有办法比这和自动矢量化代码做得更好?任何适用的内在函数?

#include "stdint.h"

void IndexedSum(float buf[], uint32_t index[], int len, float *res) {
    float acc = 0;
    for(int i = 0; i < len; i++) {
       acc += buf[index[i]];
    }
    *res = acc;
}

目前正在使用clang 6.0-O3-ffast-math-mllvm -force-vector-width=8 进行编译:

https://godbolt.org/g/AVhA4L

【问题讨论】:

  • 我唯一能想到的就是对索引进行(预)排序。
  • 应该提到它们已经排序了:)
  • 假设生成的汇编器已经有一些向量化?我会考虑将 const 放在 const 的东西上。也许发布汇编程序,我们可以看到它已经非常接近理想了。
  • 根据长度,您可能会通过穿线并在完成时添加来获得良好的回报。
  • 另外,如果你知道长度足够长,那么一点点循环展开也可能会有所帮助。不过,您需要对此进行概要分析。

标签: c clang


【解决方案1】:

展开循环。我认为类似

#include "stdint.h"

void IndexedSum(float buf[], uint32_t index[], int len, float *res)
  {
  float acc = 0;
  int   i;

  for(i = 0 ; i < len-8 ; i += 8)
    acc += (buf[index[i+0]] + 
            buf[index[i+1]]
            buf[index[i+2]]
            buf[index[i+3]]
            buf[index[i+4]]
            buf[index[i+5]]
            buf[index[i+6]]
            buf[index[i+7]])

  while(i < len)
    acc += buf[index[i++]];

  *res = acc;
  }

如果len 足够大,应该会提供改进。我考虑过使用Duff's device,但不想引入通过指针执行所有操作的潜在性能损失。不过,这可能是一个有趣的性能比较。

祝你好运。

【讨论】:

  • 这似乎不太可能比 clang 的内置展开器带来任何好处,而且很可能会因为干扰它而使事情变得更糟......
猜你喜欢
  • 1970-01-01
  • 2017-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-16
相关资源
最近更新 更多