неразрешенный внешний символ __mm256_setr_epi64x

Я написал и отладил некоторый код AVX с g ++, и теперь я пытаюсь заставить его работать с MSVC, но я продолжаю получать

ошибка LNK2019: неразрешенный внешний символ __mm256_setr_epi64x, на который ссылается функция «private: union __m256i __thiscall avx_matrix :: avx_bit_mask (unsigned int) const» (? avx_bit_mask @ avx_matrix @@ ABE? AT__m256i @@)

Ссылочный фрагмент кода

...

#include <immintrin.h>

...

/* All zeros except for pos-th position (0..255) */
__m256i avx_matrix::avx_bit_mask(const std::size_t pos) const
{
int64_t a = (pos >= 0 && pos < 64) ? 1LL << (pos - 0) : 0;
int64_t b = (pos >= 64 && pos < 128) ? 1LL << (pos - 64) : 0;
int64_t c = (pos >= 128 && pos < 192) ? 1LL << (pos - 128) : 0;
int64_t d = (pos >= 192 && pos < 256) ? 1LL << (pos - 256) : 0;
return _mm256_setr_epi64x(a, b, c, d);
}
...
  • Я включил /arch:AVX, но это не имеет никакого значения.
  • Моя машина определенно поддерживает AVX — это то же самое, что я использовал для оригинального проекта Linux.
  • Также, http://msdn.microsoft.com/en-us/library/hh977022.aspx списки _mm256_setr_epi64x среди доступных встроенных функций.

Любая помощь приветствуется.

4

Решение

Похоже, это может быть на самом деле известная ошибка — некоторые встроенные функции AVX, по-видимому, недоступны в 32-разрядном режиме. Попробуйте создать 64-разрядную версию и / или обновить до Visual Studio 2013 с обновлением 2, где это, возможно, теперь исправлено.

В качестве альтернативы, если у вас есть только один экземпляр выше, где вы используете эту встроенную функцию, то вы можете изменить свою функцию на:

__m256i avx_matrix::avx_bit_mask(const std::size_t pos) const
{
int64_t a[4] = { (pos >=   0 && pos <  64) ? 1LL << (pos -   0) : 0,
(pos >=  64 && pos < 128) ? 1LL << (pos -  64) : 0,
(pos >= 128 && pos < 192) ? 1LL << (pos - 128) : 0,
(pos >= 192 && pos < 256) ? 1LL << (pos - 256) : 0 };
return _mm256_loadu_si256((__m256i *)a);
}

или, может быть, даже:

__m256i avx_matrix::avx_bit_mask(const std::size_t pos) const
{
int64_t a[4] = { 0 };
a[pos >> 6] = 1LL << (pos & 63ULL);
return _mm256_loadu_si256((__m256i *)a);
}

который может быть быть немного более эффективным.

3

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

В 32-битном режиме MSVC не поддерживает

  • _mm_set_epi64x
  • _mm_setr_epi64x
  • _mm_set1_epi64x
  • _mm256_set_epi64x
  • _mm256_setr_epi64x
  • _mm256_set1_epi64x

В вашем случае в 32-битном режиме вы можете сделать это:

    union {
int64_t q[4];
int32_t r[8];
} u;
u.q[0] = a; u.q[1] = b; u.q[2] = c; u.q[3] = d;
return _mm256_setr_epi32(u.r[0], u.r[1], u.r[2], u.r[3], u.r[4], u.r[5], u.r[6], u.r[7]);
4

По вопросам рекламы [email protected]