【问题标题】:Need to multiply one XMM register by another, but with bit masked value需要将一个 XMM 寄存器乘以另一个,但使用位掩码值
【发布时间】:2013-02-03 07:51:40
【问题描述】:

在 x86/SIMD 程序集中,我使用需要转换的图形图像的四个 32 位像素填充了一个 XMM 寄存器。但是,像素是 10 位压缩 RGB 格式,因此它们以这种形式存在于 32 位中:

[  red   ][  green ][  blue  ][]
RRRRRRRRRRGGGGGGGGGGBBBBBBBBBB00

最后两位是填充位,未使用。

我需要将这些像素乘以另一个值,但该值需要被屏蔽,因此它只会影响红色像素。这个值是常数,所以可以硬编码。假设值为 0.1234。我如何将它放入另一个带有适当掩码的 XMM 寄存器中,以便它只影响每个 32 位段的红色部分?

以图形方式说明,我想做这样的事情:

XMM0 (first 32 bit segment):
[ 0.1234 ][  1.0   ][  1.0   ][]

*

XMM1 (first 32 bit segment):
RRRRRRRRRRGGGGGGGGGGBBBBBBBBBB00

结果是 XMM0 和 XMM1 的乘积。当然,这个 32 位段会在整个 XMM 寄存器中复制,我只是在这里指定了前 32 位,所以你明白了。

【问题讨论】:

    标签: c optimization assembly graphics


    【解决方案1】:

    如果您真的只想影响红色部分,您可能会想出一个技巧,将红色和绿色部分乘以某个常数(将寄存器视为 16 位短裤的集合)和然后将新的红色部分与旧的绿色和蓝色重新组合。

    如果您要对所有颜色进行操作,一个更好的策略是使用移位和随机播放的组合将该格式解压缩为受支持的 xmm 寄存器格式(如 16 位或 32 位短或浮点)(以及可能转换为浮动)操作。然后做所有的数学运算,然后把它打包回去。

    如果您曾经重复使用任何值(例如,如果您正在计算一个过滤器内核)并且您正在使用浮点数,那么如果您解压缩并转换为浮点数会更快一次 em> 然后一遍又一遍地重复使用该值。即使您必须创建一个循环,将整行解压缩为 32 位浮点数,然后再对其进行操作并重新打包整行。

    【讨论】:

    • 随机播放不好,因为 RGB 值被打包到 XMM 寄存器的单个 32 位分量中。虽然我同意其余的,但做一个移位和乘法移位或(和)的事情可能是最好的方法(如果有一个好的方法的话)。
    • @Damon:我的意思是PSHUFB 作为第一遍将所有 R、G 和 B 位(移位,被其他不属于的位包围)转换为 16 位或 32 位对齐,然后使用掩蔽和移位。根据您要执行的操作,您可以PSHUFB 如我所述,PAND 屏蔽不相关的位,然后直接CVTPI2PS。由于移位,一些值将被移位(例如红色总是在下面有 6 位绿色,被屏蔽,所以它是 64.0*R)但您可以将转换烘焙到乘法(即0.1234/64.0 让它按这种方式缩放以便重新打包。
    • 啊,我明白了。虽然这可能仍然不是我要做的事情,因为它创建了对 SSSE3 的依赖,它没有得到很好的支持,对于一些简单的转变可能也一样好(如果我理解正确,OP 只需要一个频道,所以这应该是微不足道的,在 R 的情况下移动 22)。另一方面,如果一个人想要所有三个频道,那么使用PSHIFB 可能会带来巨大的优势。
    • 谢谢,我能够使用 PSHUFB 将四个像素解压缩为两个 16 位/分量像素,只需使用移位和掩码(从 XMM0 中的四个像素到 XMM1 中的两个像素)。但是,似乎没有办法对以这种方式排列的数据实际执行任何数学运算。我必须将每个 32 位元素解压缩到其自己的 XMM 寄存器中吗?这个想法是采用一个 32 位压缩的 RGB 元素并将其解压缩为 4x 单精度浮点数。因此,从一个“输入”XMM 寄存器来看,我现在有四个 XMM 寄存器,它们包含每个像素为 32 位浮点数。我不需要 32 位精度,但我没有看到任何其他方式。
    • 实际上,我可以只使用三个额外的寄存器,因为我不需要 Alpha 通道。 RGB (3) * 4 像素 = 12.
    【解决方案2】:

    假设您想使用浮点来乘以您的值,我会将 R/G/B 值解压缩到 XMM 寄存器的各个浮点部分(仅除以 1023.0)中的每个值。

    您可能还会发现准备四个 R、四个 G 和四个 B 值实际上更容易,然后为另一个 XMM 寄存器中的每个颜色值构建一个具有相同乘数的值,然后乘以那个值,而不是将 R、G 和 B 保存在一个寄存器中。显然,这需要一些展开循环,但无论如何这往往会大大提高性能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-29
      • 2011-01-02
      • 2021-09-19
      • 2011-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多