AVX конвертирует 64-битное целое число в 64-битное число с плавающей запятой

Я хотел бы преобразовать 4 упакованных 64-битных целых числа в 4 упакованных 64-битных числа с плавающей запятой, используя AVX. Я пробовал что-то вроде:

int_64t *ls = (int64_t *) _mm_malloc(256, 32);
ls[0] = a;
//...
ls[3] = d;

__mm256i packed = _mm256_load_si256((__m256i const *)ls);

Что будет отображаться в отладчике:

(gdb) print packed
$4 = {1234, 5678, 9012, 3456}

Пока хорошо, но единственная операция приведения/преобразования, которую я могу найти, это _mm256i_castsi256_pd, которая не дает мне того, что я хочу:

__m256d pd = _mm256_castsi256_pd(packed);

(gdb) print pd
$5 = {6.0967700696809824e-321, 2.8053047370865979e-320, 4.4525196003213139e-320, 1.7074908720273481e-320}

То, что я действительно хотел бы видеть, это:

(gdb) print pd
$5 = {1234.0, 5678.0, 9012.0, 3456.0}

person Michael Barker    schedule 12.05.2013    source источник
comment
См. также: Лучший способ загрузить 64-битное целое число в регистр SSE2 двойной точности?. Обратите внимание, что если вы не хотите делать предположения (или использовать уродливые хаки для изменения) битов внутри вектора Packed-Double, вы всегда можете выполнить два CVTDQ2PD, один раз используя младшие 32-биты, а затем снова используя верхние 32-биты. бит, и, наконец, сложить вместе вектор Packed-Double.   -  person rwong    schedule 17.04.2015


Ответы (2)


Все встроенные функции cast выполняют побитовое приведение, поэтому вы не видите значимых результатов при этом.

Преобразование вектора (внутренняя функция cvt) между 64-битным целым числом и 64-битным числом с плавающей запятой не существует.

person Cory Nelson    schedule 13.05.2013
comment
Я предполагаю, что это было так, ура для подтверждения. Время решать проблему по-другому. - person Michael Barker; 13.05.2013
comment
Кроме того, имейте в виду, что вы не можете представлять одни и те же числа с помощью 64-битного целого и 64-битного числа с плавающей запятой. Большинство чисел в каждом формате не имеют эквивалента в другом. 64-битные числа с плавающей запятой намного больше/меньше, чем int, поэтому вы даже не можете пытаться. Переходя от int к float наилучшим возможным способом (не побитовым приведением), вы получите приближения, но не сделаете с ними ничего важного. - person xaxxon; 13.05.2013

Что бы это ни стоило, я заглянул в векторный класс Агнера Фога, чтобы увидеть, как он это делает. Он просто сохраняет 64-битные целые числа в массив и приводит каждое значение массива к типу double. Это неэффективно, но это работает.

Из файла "vectorf256.h":

// function to_double: convert integer vector elements to double vector (inefficient)
static inline Vec4d to_double(Vec4q const & a) {
    int64_t aa[4];
    a.store(aa);
    return Vec4d(double(aa[0]), double(aa[1]), double(aa[2]), double(aa[3]));
}

// function to_double: convert integer vector to double vector
static inline Vec4d to_double(Vec4i const & a) {
    return _mm256_cvtepi32_pd(a);
}
person Community    schedule 13.05.2013