繁体   English   中英

如何使用NEON在ARM组件中实现16位 - > 32位查找表?

[英]How to implement 16 bit->32 bit lookup table in ARM assembly using NEON?

在iOS 6项目中,我有一个包含两个字节字(16位)的缓冲区,需要通过查找表将其转换为四个字节字(32位)。 我将值硬编码到表中,然后使用两个字节缓冲区的值来确定要检索的32位表值。 这是一个例子:

void map_values(uint32_t *dst,uint16_t *src,uint32_t *lut,int buf_length){
    int i=0;
    for(i=0;i<buf_length;i++){

        *dst = *(lut+(*src));
        dst++;
        src++;
    }
}

问题是,它太慢了。 使用NEON一次处理4个输出字节可以加快速度吗? 问题是,我不知道如何从src缓冲区获取值并将其用作查找表的输入以确定要检索的值。 此外,表长度和输出缓冲区中的字长度相同,但源不相同。 因此,我只能读取两个16位字作为输入,而不是我需要的四个32位字输出。 有任何想法吗? 或许有更好的方法来解决这个问题吗?

来自clang的当前asm输出(clang -O3 -arch armv7 lut.c -S):

    .section    __TEXT,__text,regular,pure_instructions
    .section    __TEXT,__textcoal_nt,coalesced,pure_instructions
    .section    __TEXT,__const_coal,coalesced
    .section    __TEXT,__picsymbolstub4,symbol_stubs,none,16
    .section    __TEXT,__StaticInit,regular,pure_instructions
    .syntax unified
    .section    __TEXT,__text,regular,pure_instructions
    .globl  _map_values
    .align  2
    .code   16                      @ @map_values
    .thumb_func _map_values
_map_values:
@ BB#0:
    cmp r3, #0
    it  eq
    bxeq    lr
LBB0_1:                                 @ %.lr.ph
                                        @ =>This Inner Loop Header: Depth=1
    ldrh    r9, [r1], #2
    subs    r3, #1
    ldr.w   r9, [r2, r9, lsl #2]
    str r9, [r0], #4
    bne LBB0_1
@ BB#2:                                 @ %._crit_edge
    bx  lr


.subsections_via_symbols

查找表(几乎)是不可向量的。 使用vtbl指令可以处理非常小的查找表,但是查找表对于它来说太大了。

你在使用查找表做什么? 如果可以在没有太多工作的情况下动态计算这些值而不是查找它们,那实际上对您来说可能是一次重大胜利。

我的第一个想法是你可以从Accelerate框架的vecLib部分中的vtablelookup中获得一些运气。 签名是:

vUInt32 vtablelookup (
   vSInt32 Index_Vect,
   uint32_t *Table
);

其中vSInt32vUInt32分别是128位打包的32位有符号/无符号整数。 我相信这个功能是由ARM上的NEON支持的。 最大的问题是将你的src数组转换成32位索引,这可能会减慢速度,从而使查找矢量化的速度增加毫无意义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM