我用g ++编写并调试了一些AVX代码,现在我正试图让它与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 @@ I @ Z)
引用的代码片段是
...
#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
。任何帮助将非常感激。
看起来这可能实际上是一个known bug - 某些AVX内在函数显然在32位模式下不可用。尝试构建64位和/或升级到Visual Studio 2013 Update 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]);
从Visual Studio 2015(_MSC_VER 1900)开始,这些内在函数在32位模式下受支持。