【问题标题】:Fast Image square on (int) Image- ARM neon intrinsics - iOS Dev(int) Image-ARM neon 内在函数上的快速图像正方形 - iOS 开发
【发布时间】:2012-01-16 22:52:04
【问题描述】:

谁能告诉我一个快速的函数来找到 int 图像的每个像素的平方。我需要它用于 iOS 应用程序开发。我正在直接处理定义为的图像的内存

int *image_sqr_Baseaaddr = (int *) malloc(noOfPixels * sizeof(int));

for (int i=0; i<newNoOfPixels; i++)
     image_sqr_Baseaaddr[i] = (int) image_scaled_Baseaaddr[i] * (int) image_scaled_Baseaaddr[i];

这显然是可能的最慢的功能。我听说 iOS 上的 ARM Neon 内部函数可用于在 1 个周期内进行多个操作。也许这就是要走的路?

问题是我不是很熟悉,目前没有足够的时间学习汇编语言。因此,如果有人可以针对上述问题发布 Neon 内在代码或任何其他 C/C++ 中的快速实现,那就太好了。

我能在网上找到的唯一的 NEON 内部代码是 RGB 到灰色的代码 http://computer-vision-talks.com/2011/02/a-very-fast-bgra-to-grayscale-conversion-on-iphone/

【问题讨论】:

    标签: image-processing ios5 arm simd neon


    【解决方案1】:

    这是一个简单的 NEON 实现:

    #include <arm_neon.h>
    
    // ...
    
    int i;
    
    for (i = 0; i <= newNoOfPixels - 16; i += 16)           // SIMD loop
    {
        uint8x16_t v = vld1q_u8(&image_scaled_Baseaaddr[i]);// load 16 x 8 bit pixels
    
        int16x8_t vl = (int16x8_t)vmovl_u8(vget_low_u8(v)); // unpack into 2 x 16 bit vectors
        int16x8_t vh = (int16x8_t)vmovl_u8(vget_high_u8(v));
    
        vl = vmulq_s16(vl, vl);                             // square them
        vh = vmulq_s16(vh, vh);
    
        int32x4_t vll = vmovl_s16(vget_low_s16(vl));        // unpack to 4 x 32 bit vectors
        int32x4_t vlh = vmovl_s16(vget_high_s16(vl));
        int32x4_t vhl = vmovl_s16(vget_low_s16(vh));
        int32x4_t vhh = vmovl_s16(vget_high_s16(vh));
    
        vst1q_s32(&image_sqr_Baseaaddr[i], vll);            // store 32 bit squared values
        vst1q_s32(&image_sqr_Baseaaddr[i + 4], vlh);
        vst1q_s32(&image_sqr_Baseaaddr[i + 8], vhl);
        vst1q_s32(&image_sqr_Baseaaddr[i + 12], vhh);
    }
    for ( ; i < newNoOfPixels; ++i)                         // scalar clean up loop
    {
        int32_t p = (int32_t)image_scaled_Baseaaddr[i];
        image_sqr_Baseaaddr[i] = p * p;
    }
    

    请注意,如果 image_scaled_Baseaaddrimage_sqr_Baseaaddr 都是 16 字节对齐的,这将表现最佳。

    另请注意,上述代码未经测试,可能需要进一步工作。

    【讨论】:

    • 问题是我的输入“image_scaled_Baseaaddr”是一个未签名的 char* 图像,我需要输出“image_sqr_Baseaaddr”是一个 int * 图像。对于这种情况,上述代码需要做哪些更改??
    • OK - 我现在更新了代码,它可以读取 8 位像素值并将平方值存储到 32 位 int 数组中。
    猜你喜欢
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 2013-07-03
    • 1970-01-01
    • 2019-09-03
    • 2013-09-18
    • 2014-05-06
    • 1970-01-01
    相关资源
    最近更新 更多