在x86 / SIMD程序集中,我已经填充了一个XMM寄存器,其中包含我需要转换的四个32位像素的图形图像。但是,像素采用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位,所以你明白了。
答案 0 :(得分:3)
如果你真的只想影响红色部分,你可能会想出一个技巧,将红色和部分绿色乘以一些常数(将寄存器视为16位短路的集合)和然后重新组合新的红色部分和旧的绿色和蓝色。
如果要对所有颜色进行操作,更好的策略是使用shift和shuffle的组合将该格式解压缩为支持的xmm寄存器格式(如16或32位短或浮点数)(和可能转换为浮动)操作。然后做你所有的数学计算,然后打包回来。
如果您正在重复使用任何值(例如,如果您正在计算过滤器内核)并且您正在使用浮点数,那么如果您解压缩并转换为float 一次将会更快然后一遍又一遍地重复使用该值。即使你必须创建一个循环,在整行之前将整行解包为32位浮点数并重新打包整行。
答案 1 :(得分:2)
假设您想使用浮点乘以您的值,我会将R / G / B值解压缩到每个值的XMM寄存器(仅除以1023.0)的各个浮点部分。
您可能还会发现,准备四个R,四个G和四个B值实际上更容易,然后为另一个XMM寄存器中的每个颜色值构建一个具有相同乘数的值,并乘以该值,而不是将R,G和B保存在一个寄存器中。显然,这需要稍微展开循环,但无论如何这往往会提高性能。