在我的previous post中,我解释说我是从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....
中进一步出现。有什么想法吗?Here是完整的示例。
非常感谢你。
我正在使用
c++
(7.3.0)和以下选项-std=c++17 -Wall -Wextra -O3 -fno-tree-vectorize -mavx512f
进行编译。我已按照here的说明进行检查,并且我的CPU(2.50GHz的Intel®Core™i7-4710HQ CPU)支持AVX2。列表中是否应该有AVX-512表示对此提供支持? 最佳答案
我认为您的系统(CPU)不支持AVX-512指令。考虑official documentation;它只提到了AVX-2。 newer CPU表示AVX-512完全正常。两者都可以在“指令集扩展”部分中找到。