2012-01-16 41 views
2

有人可以告訴我一個快速函數來找到一個int圖像的每個像素的平方。我需要它的iOS應用程序開發。我直接在圖像的內存上定義爲快速圖像正方形上(int)圖像 - ARM氖內部函數 - iOS Dev

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 intrinsics代碼或者C/C++中的其他快速實現,那將是非常棒的。

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

回答

3

代碼下面是一個簡單的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字節對齊的。

還要注意,上面的代碼是未經測試的,可能需要進一步的工作。

+0

問題是我的輸入「image_scaled_Baseaaddr」是一個無符號的char *圖像,我需要輸出「image_sqr_Baseaaddr」是一個int *圖像。上述代碼對這種情況需要做什麼修改? – shreyas253 2012-01-18 10:22:42

+0

好的 - 我已經更新了代碼,因此它讀取了8位像素值並將平方值存儲到32位int數組中。 – 2012-01-18 11:51:25