代码之家  ›  专栏  ›  技术社区  ›  HaggarTheHorrible

是否将8位uint8\t作为uint32\t加载?

  •  5
  • HaggarTheHorrible  · 技术社区  · 16 年前

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

    我怎么装 四个8位像素值 同时,它们是 单位8\t ,作为 四个单元32

    我是说:

    alt text

    例如

    255 255 255 255 ......... (640 pixels)
    255 255 255 255
    255 255 255 255
    255 255 255 255
    .
    .
    .
    .
    .
    (480 pixels) 
    
    5 回复  |  直到 12 年前
        2
  •  5
  •   domen    16 年前

    例如,对于GCC来说,这可能是一个起点: http://gcc.gnu.org/onlinedocs/gcc/ARM-NEON-Intrinsics.html

        3
  •  3
  •   Exophase    15 年前

    如果您需要总计480个8位值,那么技术上需要17位中间存储。但是,如果您分两个阶段执行加法,即前240行然后后240行,则可以每个阶段16位执行加法。然后你可以把两半的结果相加得到最终的答案。

    实际上,有一条霓虹灯指令适合您的算法,称为vaddw。它将向qword向量添加一个dword向量,qword向量包含的元素宽度是前者的两倍。在您的例子中,vaddw.u8可用于向8个16位累加器添加8个像素。然后,可以使用vaddw.u16将两组8个16位累加器添加到一组8个32位累加器中—请注意,必须使用两次指令才能得到两个半累加器。

        4
  •  2
  •   Etienne    15 年前

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

    您只能使用16位寄存器。应该够了。。。

        5
  •  0
  •   fgp    14 年前

    使用单通道加载指令加载4个字节( vld1 <register>[<lane>], [<address] vmovl

    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] 而是在load指令中,保存一两个周期。但是,如果您这样做并且地址没有对齐,则会出现错误。

    嗯,我刚刚意识到你想要使用的是内部函数,而不是汇编,所以这和内部函数是一样的。

    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);
    
    推荐文章