NEON编码 - 第4部分: 左右移位

来源:互联网 发布:淘宝老司机搜索关键词 编辑:程序博客网 时间:2024/04/26 05:37

转自:http://blogs.arm.com/software-enablement/521-neon%E7%BC%96%E7%A0%81-%E7%AC%AC4%E9%83%A8%E5%88%86-%E5%B7%A6%E5%8F%B3%E7%A7%BB%E4%BD%8D/

NEON编码 - 第4部分: 左右移位

本文将介绍NEON提供的移位运算,并显示如何利用移位运算在常用颜色深度之间转换影像数据。本系列前期已发布的文章包括:第1部分:加载与存储,第2部分:余数的处理,第3部分:矩阵乘法。

向量移位NEON上的移位与标量ARM编码中可能用到的移位非常相似,即每个向量元素的位数均向左或向右移位,出现在每个元素左侧或右侧的位将被删除;它们不能移位至相邻的元素。

移位的数量可通过指令中编码的文字或附加的移位向量来指定。使用移位向量时,应用到输入向量每个元素的移位取决于移位向量中对应元素的值。移位向量中的元素被当作带符号的值来处理,因此按元素分配,左移位、右移位和零移位都有可能发生。

Attached Image

带符号元素的向量上发生的右移位由指令附加的类型指定,并会将符号扩展至每一个元素。这与ARM编码中可能用到的算术移位相同。应用到无符号向量的移位不会发生符号扩展。

移位与插入NEON也支持通过插入产生移位,使两个不同向量的位相结合。例如,左移位与插入(VSLI)可使源向量的每一个元素均向左移位。每个元素右侧新插入的位就是目标向量中的对应位。

Attached Image

移位与计算最后,NEON还支持向量元素向右移位,并将结果计入到另一个向量中。这种方法对于先在高精度条件下进行临时计算,然后再将结果与低精度计算器相结合的情况非常有用。

指令修改器每个移位指令都能拥有一个或多个修改器。这些修改器并不改变移位运算本身,而是通过调整输入值或输出值,消除偏差或饱和状况,保持一定的范围。共有五种移位修改器:

  • 舍位修改器 (Rounding),以R前缀表示,可以纠正右移时舍位导致的偏差。
  • 窄修改器 (Narrow),以N后缀表示,可以让结果中每个元素的位数减半。它代表Q(128位)源和D(64位)目标寄存器。
  • 长修改器 (Long),以L后缀表示,可以让结果中每个元素的位数加倍。它代表D源和Q目标寄存器。饱和修改器 (Saturating),以Q前缀表示,可以在最大和最小可表范围内设置每个结果元素,前提是结果未超出该范围。向量的位数和符号类型可用于确定饱和范围。
  • 无符号饱和修改器 (Unsigned Saturating),以Q前缀和U后缀表示,与饱和修改器类似,但在进行带符号或无符号输入时,结果将在无符号范围内表现为饱和。

这些修改器的部分组合并未表现出有用的运算,因此NEON也没有提供相应指令。例如,饱和右移位(应称为VQSHR)其实就毫无必要,因为右移位只会让结果变得更小,因而值根本无法超出有效范围。

可用移位表NEON提供的所有移位指令均在下表中列出。它们根据先前提到的修改器进行排列。如果你还是不太确定修改器各个字母代表的含义,请利用下表选择需要的指令。

Attached Image

示例:转换颜色深度颜色深度之间的转换是图形处理中经常需要的运算。通常,输入或输出数据都是RGB565 16位颜色格式,但RGB888格式的数据处理起来更为方便。对于NEON而言尤其如此,因为它无法为RGB565这样的数据类型提供本机支持。

Attached Image

但是,NEON仍然可以有效地处理RGB565数据,上文中介绍的向量移位便提供了处理方法。

从565到888首先,我们来看如何将RGB565转换为RGB888。假设寄存器q0中有8个16位像素,我们想要在d2、d3和d4这三个寄存器中将红色、绿色和蓝色分离成8位的元素。

Attached Image

每个指令的效果都在上面备注中做了描述,但总而言之,每个通道上执行的运算为:

  • 利用移位推掉元素任意一端的位数,清除相邻通道的颜色数据。
  • 使用第二次移位将颜色数据放置到每个元素最重要的位上,并缩短位数将元素大小从16位减至8位。

请注意在这个顺序中使用元素大小来确定8位和16位元素的位置,以进行部分掩码运算。

一个小问题你可能会注意到,如果使用上述代码转换到RGB888格式,白色显得不够白。这是因为,对于每个通道而言,最低的2或3位是零,而不是1;白色在RGB565中表示为(0x1F, 0x3F, 0x1F),而在RGB888中,却变成了 (0xF8, 0xFC, 0xF8)。这可以通过移位来解决,将部分最重要的位插入到低位。

从888到565现在,我们来看反向运算,即从RGB888转换为RGB565。这里,我们假设RGB888数据为上述代码产生的格式;在d0、d1和d2这三个寄存器上,每个寄存器均包含每种颜色的8个元素。结果将存储为q2格式的8个16位RGB565元素。

Attached Image

同样,每个指令的详细说明在备注中列出,但总而言之,对于每个通道而言:

  • 将每个元素的长度扩展至16位,并将颜色数据移至最重要的位上。
  • 使用插入右移位,将每个颜色通道放置到结果寄存器中。

结论NEON提供的强大的移位指令范围让你能够:

  • 利用舍入和饱和,通过二次幂快速进行向量的除法和乘法运算。
  • 通过移位将一个向量位复制到另一个向量位。
  • 在高精度条件下进行临时计算,并在低精度条件下计算结果。

下一篇文章,我们将看到NEON提供的部分其他数据处理指令。

View this post in English.


Martyn是处理器领域的资深软件工程师已在ARM工作了近10年。他主要负责改善ARM平台上软件的性能和体验。他对使用汇编语言和SIMD实现软件优化非常感兴趣,尤其是在图形和多媒体领域。

Martyn is a staff software engineer in the processor division, and has been at ARM for almost 10 years. He works on improving software performance and experience on ARM platforms. He's interested in software optimization using assembly language and SIMD, particularly in the areas of graphics and multimedia.
All company and product names appearing in the ARM Blogs are trademarks and/or registered trademarks of ARM Limited per ARM’s official trademark list. All other product or service names mentioned herein are the trademarks of their respective owners.
Back to Software Enablement →

1 Comments On This Entry

Please log in above to add a comment or register for an account

第一頁

pinaudio 

29 July 2011 - 04:33 AM
从2008年开始,就接触Neon,并做过很多Codec在Cortex-A8上的优化。Neon相当强大,但你要写出高效的Neon也是要花很长时间去摸索的。十分感觉Martyn经验共享。Thanks.Email: liupin.2008@gmail.comBlog:http://www.cnblogs.com/huaping-audio/
原创粉丝点击