当使用SSE2指令(例如PADDD
(即_mm_add_epi32
固有))时,是否可以检查任何操作是否溢出?
我以为MXCSR控制寄存器上的标志可能在溢出后被置位,但我看不到这种情况。例如,在以下两种情况下,_mm_getcsr()
都会输出相同的值(8064):
#include <iostream>
#include <emmintrin.h>
using namespace std;
void main()
{
__m128i a = _mm_set_epi32(1, 0, 0, 0);
__m128i b = _mm_add_epi32(a, a);
cout << "MXCSR: " << _mm_getcsr() << endl;
cout << "Result: " << b.m128i_i32[3] << endl;
__m128i c = _mm_set_epi32((1<<31)-1, 3, 2, 1);
__m128i d = _mm_add_epi32(c, c);
cout << "MXCSR: " << _mm_getcsr() << endl;
cout << "Result: " << d.m128i_i32[3] << endl;
}
还有其他方法可以检查SSE2是否溢出?
最佳答案
这是@hirschhornsalz's sum_and_overflow
function的效率更高的版本:
void sum_and_overflow(__v4si a, __v4si b, __v4si& sum, __v4si& overflow)
{
__v4si sa, sb;
sum = _mm_add_epi32(a, b); // calculate sum
sa = _mm_xor_si128(sum, a); // compare sign of sum with sign of a
sb = _mm_xor_si128(sum, b); // compare sign of sum with sign of b
overflow = _mm_and_si128(sa, sb); // get overflow in sign bit
overflow = _mm_srai_epi32(overflow, 31); // convert to SIMD boolean (-1 == TRUE, 0 == FALSE)
}
它使用表达式从Hacker's Delight第27页进行溢出检测:
sum = a + b;
overflow = (sum ^ a) & (sum ^ b); // overflow flag in sign bit
请注意,溢出 vector 将包含更常规的SIMD bool 值,对于TRUE(溢出)为-1,对于FALSE(无溢出)为0。如果只需要符号位中的溢出,而其他位是“无关位”,则可以省略函数的最后一行,将SIMD指令的数量从5个减少到4个。
注意:此解决方案以及previous solution on which it is based均用于带符号整数值。对于无符号值的解决方案将需要稍微不同的方法(请参见@Stephen Canon的answer)。
关于c++ - SSE2整数溢出检查,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10511000/