Вот простая реализация 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_Baseaaddr
, и image_sqr_Baseaaddr
выровнены по 16 байтов.
Обратите внимание, чтоприведенный выше код не протестирован и может потребовать дальнейшей работы.