gre*_*til 5 arm image image-processing simd neon
我有一个8位640x480图像,我想缩小到320x240图像:
void reducebytwo(uint8_t *dst, uint8_t *src)
//src is 640x480, dst is 320x240
Run Code Online (Sandbox Code Playgroud)
使用ARM SIMD NEON最好的方法是什么?在某处有任何示例代码?
作为一个起点,我只想做相当于:
for (int h = 0; h < 240; h++)
for (int w = 0; w < 320; w++)
dst[h * 320 + w] = (src[640 * h * 2 + w * 2] + src[640 * h * 2 + w * 2 + 1] + src[640 * h * 2 + 640 + w * 2] + src[640 * h * 2 + 640 + w * 2 + 1]) / 4;
Run Code Online (Sandbox Code Playgroud)
这是您的代码的一对一翻译,以支持NEON内在函数:
#include <arm_neon.h>
#include <stdint.h>
static void resize_line (uint8_t * __restrict src1, uint8_t * __restrict src2, uint8_t * __restrict dest)
{
int i;
for (i=0; i<640; i+=16)
{
// load upper line and add neighbor pixels:
uint16x8_t a = vpaddlq_u8 (vld1q_u8 (src1));
// load lower line and add neighbor pixels:
uint16x8_t b = vpaddlq_u8 (vld1q_u8 (src2));
// sum of upper and lower line:
uint16x8_t c = vaddq_u16 (a,b);
// divide by 4, convert to char and store:
vst1_u8 (dest, vshrn_n_u16 (c, 2));
// move pointers to next chunk of data
src1+=16;
src2+=16;
dest+=8;
}
}
void resize_image (uint8_t * src, uint8_t * dest)
{
int h;
for (h = 0; h < 240 - 1; h++)
{
resize_line (src+640*(h*2+0),
src+640*(h*2+1),
dest+320*h);
}
}
Run Code Online (Sandbox Code Playgroud)
它处理32个源像素,每次迭代生成8个输出像素.
我快速查看了汇编器输出,看起来没问题.如果在汇编程序中编写resize_line函数,则可以获得更好的性能,展开循环并消除管道停顿.这将为您提供三个性能提升的估计因素.
它应该比没有汇编程序更改的实现快得多.
注意:我没有测试过代码......
这是@Nils Pipenbrinck 建议的reduce_line 上的asm 版本
static void reduce2_neon_line(uint8_t* __restrict src1, uint8_t* __restrict src2, uint8_t* __restrict dest, int width) {
for(int i=0; i<width; i+=16) {
asm (
"pld [%[line1], #0xc00] \n"
"pld [%[line2], #0xc00] \n"
"vldm %[line1]!, {d0,d1} \n"
"vldm %[line2]!, {d2,d3} \n"
"vpaddl.u8 q0, q0 \n"
"vpaddl.u8 q1, q1 \n"
"vadd.u16 q0, q1 \n"
"vshrn.u16 d0, q0, #2 \n"
"vst1.8 {d0}, [%[dst]]! \n"
:
: [line1] "r"(src1), [line2] "r"(src2), [dst] "r"(dest)
: "q0", "q1", "memory"
);
}
}
Run Code Online (Sandbox Code Playgroud)
它比 C 版本快约 4 倍(在 iPhone 5 上测试)。
| 归档时间: |
|
| 查看次数: |
2128 次 |
| 最近记录: |