ios - 我如何向量化这个 for 循环?

标签 ios c arm vectorization neon

我有这个循环

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/

相关文章:

c - 如何将 KdPrint 定义为 DbgPrint?

c - K22F 上的 I2C 初始化作为主机

ios - 剩余的 UITextView 字符数

ios - 如何在缓存中存储图像数据

c - C 语言维吉尼亚密码

检查两条给定线段是否相交但不包括接触点

c++ - 告诉编译器我希望变量始终存储在寄存器中的正确方法是什么?

linux - arm linux 系统调用中 vector_swi() 中使用的堆栈指针是如何初始化的?

iphone - 以米为单位的 startMonitoringForRegion 的最小精度

iphone - 检查配置文件的开发人员证书有效性