Вычитание целочисленного результата сравнения с SSE - PullRequest
0 голосов
/ 17 сентября 2018

Я изучаю кодирование 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 из n если a имеет отрицательное значение?

(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;
}
...