我的图像处理项目可与灰度图像一起使用。我有ARM Cortex-A8处理器平台。我想利用霓虹灯。

我有一个灰度图像(请考虑下面的示例),在我的alogorithm中,我只需添加列。

我如何加载 四个8位像素值 并行, uint8_t, , 作为 四个UINT32_T 进入128位霓虹灯登记册之一?我必须使用什么内在的来做到这一点?

我是说:

alt text

我必须将它们作为32位加载,因为如果您仔细看,我做255 + 255是512的那一刻,不能在8位寄存器中保存。

例如

255 255 255 255 ......... (640 pixels)
255 255 255 255
255 255 255 255
255 255 255 255
.
.
.
.
.
(480 pixels) 
有帮助吗?

其他提示

取决于您的编译器和(可能缺乏)扩展。

IE。对于GCC,这可能是一个起点: http://gcc.gnu.org/onlinedocs/gcc/arm-neon-intrinsics.html

如果您需要总结480个8位值,那么从技术上讲,您将需要17位中间存储。但是,如果您分两个阶段进行添加,即,前240行,则可以进行底部240行,则可以分别以16位进行操作。然后,您可以添加两半中的结果以获取最终答案。

实际上,有一个适合您的算法称为VADDW的霓虹灯指令。它将在QWORD向量中添加DWORD向量,后者包含的元素是前者的两倍。在您的情况下,vaddw.u8可用于将8个像素添加到8个16位蓄能器中。然后,VADDW.U16可用于将两组8个16位蓄能器添加到一组8 32位的累加器中 - 请注意,您必须使用两次指令才能获得两半。

如有必要,您还可以使用VMOVN或VQMOVN将值转换回16位或8位。

没有指示可以将您的4 8位值加载到4 32位寄存器中。

您必须加载它们,然后使用VSHL两次。因为霓虹灯不能使用32个寄存器,您必须在8个像素上工作(而不是4个像素)

您只能使用16bits寄存器。应该足够...

使用单车道负载指令加载4个字节(vld1 <register>[<lane>], [<address])进入Q-Register,然后使用两个移动的说明(vmovl)将它们首先提升为16,然后将其提升到32位。结果应该是(在GNU语法中)

vld1 d0[0], [<address>] @Now d0 = (*<addr>, *<addr+1>, *<addr+2>, *<addr+3>, <junk>, ... <junk> )
vmovl.u8 q0, d0 @Now q1 = (d0, d1) = ((uint16_t)*<addr>, ... (uint16_t)*<addr+3>, <junk>, ... <junk>)
vmovl.u16 q0, d2 @Now d0 = ((uint32_t)*<addr>, ... (uint32_t)*<addr+3>), d1 = (<junk>, ... <junk>)

如果你能保证 <address> 是4字节对齐,然后写 [<address>: 32] 而是在负载指令中保存一两个周期。如果您这样做并且地址不一致,但是您会遇到错误。

嗯,我只是意识到您想使用内在的,而不是组装,所以这与Intrinsics是同一件事。

uint32x4_t v8; // Will actually hold 4 uint8_t
v8 = vld1_lane_u32(ptr, v8, 0);
const uint16x4_t v16 = vget_low_u16(vmovl_u8(vreinterpret_u8_u32(v8)));
const uint32x4_t v32 = vmovl_u16(v16);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top