我正在学习SSE编码,现在在移植/向量化exp(double)
函数时停留在几行代码上。
我也是C / C ++编码的初学者,因此这两行令人困惑,我不知道那里发生了什么:
fast_exp(double x) {
double a = c1 * x + 0.5;
int n = (int)a; // truncate toward zero
ieee754 u; // union of double and unsigned short[4]
n -= (a < 0); //(1)
...
u.s[3] = (unsigned short)((n << 4) & 0x7FF0); //(2)
return u.d;
}
在那里做什么?
(1)如果a保持负值,是否从a
中减去n
?
(2)?按位左移,但是在那里还会发生什么?
然后,如何使用SSE内部函数编写这两行代码?
这是到目前为止,部分移植到SSE内在函数。在下面的代码中,我卡住的行用 ?? 标记。它尚未编译。
typedef union {
double d;
unsigned short s[4];
} ieee754;
double exp_sse (double value){
double px; //, a;
ieee754 u;
__m128i n;
__m128d a;
__m128d x = _mm_set1_pd (x);
__m128d c1 = _mm_set1_pd (1.4426950408889634073599);
__m128d c2 = _mm_set1_pd (6.93145751953125E-1);
__m128d c3 = _mm_set1_pd (1.42860682030941723212E-6);
__m128i c1023 = _mm_set1_epi32(1023);
__m128d c4 = _mm_set1_pd (0.5);
/* n = round(x / log 2) --------------------- */
// a = c1 * x + 0.5;
a = _mm_mul_pd (c1, x);
a = _mm_add_pd (a, c4);
// n = (int)a;
n = _mm_cvtpd_epi32(a);
n -= (a < 0); ??
/* x -= n * log2 ---------------------- */
//px = (double)n;
px = _mm_cvtepi32_pd(n);
//x -= px * c2;
x = _mm_sub_pd(x, _mm_mul_pd(px, c2));
//x -= px * c3;
x = _mm_sub_pd(x, _mm_mul_pd(px, c3));
// calc e^x -------------------
...
// ----------------------------
/* 2^n in double. */
n = _mm_add_(n, c1023);
u.s[3] = (unsigned short)((n << 4) & 0x7FF0); ??
return d[0] * u.d;
}