我正在NEON中编写一个用于图像处理的子程序,它进行颜色交换,即,我顺序加载数组中的R,G,B通道,并根据某些配置,置换其中的一些。
最多6个permutes
(RGB) -> { (RGB),(RBG),(GRB),(GBR),(BRG),(BGR) }
最有效的方法是为每个案例和相应的VSWP指令分别设置一个子程序。由于子程序将执行其他几项操作,我宁愿将所有内容保留在一个子程序中,即使它不是那么有效,
另请注意,不建议使用条件执行和分支。所以,如果我想把它放在一个无分支代码的块中,我唯一想到的就是
New_R = a(0)*R+a(1)*G+a(2)*B
New_G = a(3)*R+a(4)*G+a(5)*B
New_B = a(6)*R+a(7)*G+a(8)*B
每个行和列中只有一个a(i)每次= 1,其余的将是= 0
问题:任何更聪明的方法,记住它必须编码为NEON?
答案 0 :(得分:1)
VTBL.8
是NEON中交换字节最强大的工具。
将3x8字节加载到寄存器d0,d1,d2看起来像
R G B R G B R G | B R G B R G B R | G B R G B R G B |
0 1 2 3 4 5 6 7 8 9 a b c d e f .... 17
VTBL d3, { d0,d1,d2 }, d6 ;; select bytes to d3 from d0,d1,d2 based on d6
VTBL d4, { d0,d1,d2 }, d7
VTBL d5, { d0,d1,d2 }, d8
其中d6,d7,d8编码要在新字节中读取的位置。 例如'0 1 2 3 4 5 6 7'用于原始排列,'0 2 1 3 5 4 6 8','7 ...'用于交换G和B.常量向量d6..d8需要加载一旦在例程的开始。
另一种可能性是使用交错读取编码以下序列;
VLD3.8 { d0,d1,d2 }, [r0] ; // Read R, G, B to separate registers
VLD3.8 { d3,d4,d5 }, [r0] ; // Make a second copy (or use some other instruction)
VBIT d3, d1, d6 ; // d3 is now either R or G
VBIT d4, d2, d7 ; // d4 is now either G or B
VBIT d5, d0, d8 ; // d5 is now either B or R
VBIT d0, d4, d9 ; // d0 is now R or (G or B)
VBIT d1, d5, d10 ; // d1 is now G or (B or R)
VBIT d2, d3, d11 ; // d2 is now B or (R or G)
即使在示例中使用了6个条件代码寄存器,但3个独立寄存器应该足够 - 如果需要使用反向逻辑,也可以使用VBIF。