我有这个循环
void f1(unsigned char *data, unsigned int size) {
unsigned int A[256] = {0u};
for (register unsigned int i = 0u; i < size; i++) {
++A[data[i]];
}
...
有没有办法手动矢量化它?
最佳答案
由于 data[i]
中的多个条目可能包含相同的值,我不明白如何简单地将其矢量化,因为可能存在竞争条件。矢量化的要点是每个元素都独立于其他元素,因此可以并行计算。但是您的算法不允许这样做。 “矢量化”与“让速度更快”不是一回事。
您在这里构建的似乎是一个直方图,而 iOS 内置了对此的优化支持。您可以创建单 channel 、单行图像并像这样使用 vImageHistogramCalculation_Planar8
:
void f1(unsigned char *data, unsigned int size) {
unsigned long A[256] = {0u};
vImage_Buffer src = { data, 1, size, size };
vImage_Error err = vImageHistogramCalculation_Planar8(&src, A, kvImageDoNotTile);
if (err != kvImageNoError) {
// error
}
...
}
不过,要小心假设这总是胜利。这取决于您的数据大小。进行函数调用非常昂贵,因此可能需要数百万字节的数据才能使它物有所值。如果您在比那个更小的集合上计算它,那么一个简单的、编译器优化的循环通常是最好的方法。您需要在真实设备上对此进行分析,以查看哪种速度更快。
只需确保通过打开 -Ofast
(最快,积极)允许编译器应用所有矢量化优化。在这种情况下这无关紧要,因为您的循环不能简单地矢量化。但总的来说,-Ofast
允许编译器在可能会略微增加代码大小的情况下应用矢量化优化(这在默认的 -Os
下是不允许的)。 -Ofast
还允许在如何执行 float 学方面有一点草率,因此不应在需要严格的 IEEE 浮点一致性的情况下使用(但 iOS 应用程序几乎从来没有这种情况,所以-Ofast
几乎总是正确的设置)。
关于ios - 我如何向量化这个 for 循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27690855/