C++ SSE 命令反转寄存器值
Posted
技术标签:
【中文标题】C++ SSE 命令反转寄存器值【英文标题】:C++ SSE commands invert register values 【发布时间】:2013-08-30 15:11:50 【问题描述】:我有一个包含一些 int 值的数组([position%2=0] 处的值为负,[position%2=1] 处的值为正)。
我想以 4 步将这些值从数组加载到寄存器,但我希望它们反转(正转换为负,反之亦然)
__m128i v1;
for (int k = 0; k < limit; k += 4)
v1 = _mm_load_si128((__m128i *) & myArray[position + k]);
上面的 SSE 代码将值按原样加载到寄存器中:是否有命令取 v1 并将其反转?可以一步/命令完成吗?甚至可以直接从原始数组加载值吗?
任何帮助将不胜感激。提前致谢。
【问题讨论】:
如果您希望 -1 为 1 且 2 为 -2 则称为“否定”。反转是按位不,即反转值中的所有位,所以 -1 将变为 0 【参考方案1】:假设你的整数元素是 32 位,那么你可以从 0 中减去,例如
v1 = _mm_load_si128(...); // load data
v1 = _mm_sub_epi32(_mm_set1_epi32(0), v1); // negate all elements
【讨论】:
【参考方案2】:另一种方法是:
__m128i v1 = _mm_xor_si128(
_mm_load_si128((__m128i *)&myArray[position + k]),
_mm_cmpeq_epi8(v1, v1)
);
基本上我们正在这样做:x ^ -1
假设我们使用的是带有二进制补码的机器,所以 -1 是一个全1的序列......
注意以下内容,其中~
表示反转,^
表示异或。
~0 == 1 == (0 ^ 1)
~1 == 0 == (1 ^ 1)
_mm_cmpeq_epi8(a, a)
将设置全 1,而您可以使用 _mm_set1_epi32(-1)
,它实际上可能会更慢,因为它可能会产生内存访问,如果性能是一个问题,我建议进行分析...
【讨论】:
以上是关于C++ SSE 命令反转寄存器值的主要内容,如果未能解决你的问题,请参考以下文章
使用 SSE 将浮点值从 Assembler DLL 返回到 C++