在iPhone上将未签名的字符图像转换为浮点图像的最快方法

Fastest way to convert an unsigned char image to a float image on iPhone

本文关键字:图像 转换 方法 字符 iPhone      更新时间:2023-10-16

我需要将一个无符号的char图像(640x480x1)或更小的图像转换为浮点图像进行处理。由于问题的复杂性,我不能在这种情况下进行定点计算。我目前使用的霓虹灯单元分两步进行。neon可以相当快地将整数转换为浮点,但不能将无符号字符转换为浮点。

1) 使用LUT将无符号字符图像转换为整数图像(由于我知道范围,所以没有通用的强制转换)2) 使用霓虹灯将整数转换为浮动

这个过程大约需要10-15毫秒来准备处理的图像。

我也可以在第一步中使用LUT,直接转换为浮点。然而,我发现这样做比使用NEON从整数到浮点需要更长的时间。因此,我实际上想使用NEON直接从无符号字符转换为浮点字符,并去掉步骤1。

有人知道更好的方法吗?

  • 如果您无论如何都要使用LUT,只需使用必要的浮点值即可
  • 如果您不介意iOS 4的要求,请参阅vDSP_vflt8()

EDIT:"unsigned char to int conversion"只需要在正确的位置添加一些零字节。显而易见的方法是执行必要的移位,然后VDUP清除一个矢量,然后VMOV.U8四次。这似乎有点慢。

更快的方法可能是VTBL:

; load stuff into D4 (e.g. {6,7,8,9,a,b,c,d})
; D5 already contains {0,-1,-1,-1,1,-1-1-1}
; D6 already contains {2,-1,-1,-1,3,-1-1-1}
; D7 and D8 are similar...
vtbl.8 D0,{D4},D5
vtbl.8 D1,{D4},D6
vtbl.8 D2,{D4},D7
vtbl.8 D3,{D4},D8
; Now Q0 should contain {6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0}; similarly for Q1
; Interpret them as (little-endian) 32-bit ints and convert them to floats
vcvt.f32.u32 Q0,Q0,#0
vcvt.f32.u32 Q1,Q1,#0
; And save them somewhere

当然,您可以指定#8而不是#0来将所有内容除以256。

我没有看到VTBL的四字版本,但这样的重写不会太难。显而易见的扩展是将四字加载到Q2={D4,D5},并重复指定D4而不是D5的过程(或者使用更多寄存器以避免数据依赖暂停)。

其他优化包括预加载缓存(我忘记了相应的ARM指令是什么)。总的来说,如果不付出很大的努力,你可能会发现很难击败Accelerate.framework。

另一种更紧凑的方法是:

; load stuff into D4 (e.g. {6,7,8,9,a,b,c,d})
vmovl.u8        q1, d4
vmovl.u16       q0, d2
vmovl.u16       q1, d3
; Now Q0 should contain {6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0}; similarly for Q1
; Interpret them as (little-endian) 32-bit ints and convert them to floats
vcvt.f32.u32 Q0,Q0,#0
vcvt.f32.u32 Q1,Q1,#0
; And save them somewhere