AVX512 незаконная инструкция

В моем предыдущий пост Я объясняю, что я начинаю с AVX, чтобы ускорить мой код (обратите внимание, что, хотя есть общие части, этот пост относится к AVX512, а предыдущий — к AVX2, которые, насколько я знаю, немного отличаются и нуждаются в разных флагах компиляции) , После экспериментов с AVX2 я решил попробовать AVX512 и изменил свою функцию AVX2:

void getDataAVX2(u_char* data, size_t cols, std::vector<double>& info)
{
__m256d dividend = _mm256_set_pd(1 / 64.0, 1 / 64.0, 1 / 64.0, 1 / 64.0);
info.resize(cols);
__m256d result;
for (size_t i = 0; i < cols / 4; i++)
{
__m256d divisor = _mm256_set_pd((double(data[4 * i + 3 + cols] << 8) + double(data[4 * i + 2 * cols + 3])),
(double(data[4 * i + 2 + cols] << 8) + double(data[4 * i + 2 * cols + 2])),
(double(data[4 * i + 1 + cols] << 8) + double(data[4 * i + 2 * cols + 1])),
(double(data[4 * i + cols] << 8) + double(data[4 * i + 2 * cols])));
result = _mm256_sqrt_pd(_mm256_mul_pd(divisor, dividend));
info[size_t(4 * i)] = result[0];
info[size_t(4 * i + 1)] = result[1];
info[size_t(4 * i + 2)] = result[2];
info[size_t(4 * i + 3)] = result[3];
}
}

для того, что я думаю, должно быть его эквивалентом:

void getDataAVX512(u_char* data, size_t cols, std::vector<double>& info)
{
__m512d dividend = _mm512_set_pd(1 / 64.0, 1 / 64.0, 1 / 64.0, 1 / 64.0, 1 / 64.0, 1 / 64.0, 1 / 64.0, 1 / 64.0);
info.resize(cols);
__m512d result;
for (size_t i = 0; i < cols / 8; i++)
{
__m512d divisor = _mm512_set_pd((double(data[4 * i + 7 + cols] << 8) + double(data[4 * i + 2 * cols + 7])),
(double(data[4 * i + 6 + cols] << 8) + double(data[4 * i + 2 * cols + 6])),
(double(data[4 * i + 5 + cols] << 8) + double(data[4 * i + 2 * cols + 5])),
(double(data[4 * i + 4 + cols] << 8) + double(data[4 * i + 2 * cols + 4])),
(double(data[4 * i + 3 + cols] << 8) + double(data[4 * i + 2 * cols + 3])),
(double(data[4 * i + 2 + cols] << 8) + double(data[4 * i + 2 * cols + 2])),
(double(data[4 * i + 1 + cols] << 8) + double(data[4 * i + 2 * cols + 1])),
(double(data[4 * i + cols] << 8) + double(data[4 * i + 2 * cols])));
result = _mm512_sqrt_pd(_mm512_mul_pd(divisor, dividend));
info[size_t(4 * i)] = result[0];
info[size_t(4 * i + 1)] = result[1];
info[size_t(4 * i + 2)] = result[2];
info[size_t(4 * i + 3)] = result[3];
info[size_t(4 * i + 4)] = result[4];
info[size_t(4 * i + 5)] = result[5];
info[size_t(4 * i + 6)] = result[6];
info[size_t(4 * i + 7)] = result[7];
}
}

который в не AVX форме:

void getData(u_char* data, size_t cols, std::vector<double>& info)
{
info.resize(cols);
for (size_t i = 0; i < cols; i++)
{
info[i] = sqrt((double(data[cols + i] << 8) + double(data[2 * cols + i])) / 64.0);
;
}
}

После компиляции кода я получаю следующую ошибку:

Illegal instruction (core dumped)

К моему удивлению, эта ошибка возникает в вызове sqrt в getData функция. Если я удалю sqrt вызовите, то ошибка появляется еще дальше, в __m512d divisor = _mm512_set_pd((d...., Есть идеи о том, что происходит?

Вот это полный пример.

Большое спасибо.

Я собираю с c++ (7.3.0) со следующими параметрами -std=c++17 -Wall -Wextra -O3 -fno-tree-vectorize -mavx512f, Я проверил как объяснил Вот и мой процессор (Intel® Core® TM i7-4710HQ CPU @ 2,50 ГГц) поддерживает AVX2. Должен ли в списке быть AVX-512 для поддержки этого?

0

Решение

Я не думаю, что инструкции AVX-512 поддерживаются в вашей системе (CPU). Принимая официальная документация во внимание; в нем упоминается только AVX-2. более новый процессор будет указывать AVX-512 совершенно нормально. Оба могут быть найдены в разделе «Расширения набора инструкций».

3

Другие решения

Других решений пока нет …