【发布时间】:2020-12-12 07:15:41
【问题描述】:
我正在尝试优化将灰度图像转换为在 Neon A64/v8 上运行的浮动图像的代码。
使用 OpenCV 的 convertTo()(为 android 编译)当前的实现相当快,但这仍然是我们的瓶颈。
所以我想出了以下代码,并希望了解可能的改进。
如果可以的话,图像的高度和宽度是 16 倍。
我正在运行for 循环:
static void u8_2_f(unsigned char* in, float* out)
{
//1 u8x8->u16x8
uint8x8_t u8x8src = vld1_u8(in);
uint16x8_t u16x8src = vmovl_u8(u8x8src);
//2 u16x8 -> u32x4high, u32x4low
uint32x4_t u32x4srch = vmovl_u16(vget_high_u16(u16x8src));
uint32x4_t u32x4srcl = vmovl_u16(vget_low_u16(u16x8src));
//3 u32x4high, u32x4low -> f32x4high, f32x4low
vst1q_f32(out, vcvtq_f32_u32(u32x4srch));
vst1q_f32(out+4, vcvtq_f32_u32(u32x4srcl));
}
【问题讨论】:
-
如果内存带宽是一个瓶颈,作为内存瓶颈图像的其他传递的一部分,它可能值得在运行中执行此操作。或者作为 ALU 瓶颈的传递的一部分,并保存图像的浮动版本以供以后使用,同时在已经加载时使用它,因此该传递保持内存繁忙以及 ALU。或者可能缓存阻止转换,以便您转换适合 L1d 或 L2 缓存的部分,然后在以后的传递中循环。
-
编写汇编代码的最大原因之一是
vget_。编译器一看到它们就会生成 FUBAR 机器代码。
标签: c++ c simd intrinsics neon