Я написал и отладил некоторый код 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
, но это не имеет никакого значения._mm256_setr_epi64x
среди доступных встроенных функций.Любая помощь приветствуется.
Похоже, это может быть на самом деле известная ошибка — некоторые встроенные функции 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);
}
который может быть быть немного более эффективным.
В 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]);