【问题标题】:AVX512 illegal instructionAVX512非法指令
【发布时间】:2019-01-20 21:46:31
【问题描述】:

在我的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(Intel(R) Core(TM) i7-4710HQ CPU @ 2.50GHz)支持 AVX2。该列表是否应该有 AVX-512 来表明对此的支持?

【问题讨论】:

  • 如果您使用-march=native 进行编译,您的编译器会告诉您,如果未启用 AVX512,您将无法使用 AVX512 内部函数。 (因为它会检测到您的 CPU 没有 AVX512。)显然您没有使用 g++ -O3 -mavx2 进行编译,因为只有 MSVC 允许在不启用相关指令集的情况下使用内部函数。 (用于运行时调度)。我认为这是一个编辑错误,因为您在上一个问题中提到使用 -mavx512f

标签: c++ avx512


【解决方案1】:

我认为您的系统 (CPU) 不支持 AVX-512 指令。考虑到official documentation;它只提到了AVX-2。 newer CPU 表示 AVX-512 非常好。两者都可以在“指令集扩展”部分下找到。

【讨论】:

  • 没错,OP 的 i7-4710HQ 是 Haswell,而不是 Skylake-X 或 Xeon Phi。
猜你喜欢
  • 1970-01-01
  • 2021-02-01
  • 2020-12-20
  • 2013-04-05
  • 2021-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多