Pertanyaan simbol eksternal yang belum terselesaikan __mm256_setr_epi64x


Saya telah menulis dan men-debug beberapa kode AVX dengan g ++ dan sekarang saya mencoba membuatnya bekerja dengan MSVC, tetapi saya terus mendapatkan

error LNK2019: simbol eksternal yang belum terselesaikan __mm256_setr_epi64x dirujuk dalam fungsi "private: union __m256i __thiscall avx_matrix :: avx_bit_mask (unsigned int) const" (? avx_bit_mask @ avx_matrix @@ ABE? AT__m256i @@ I @ Z)

Potongan kode yang direferensikan adalah

...

#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);
    }
...
  • Saya telah diaktifkan /arch:AVX, tetapi tidak ada bedanya.
  • Mesin saya benar-benar mendukung AVX - itu sama dengan yang saya gunakan untuk proyek Linux asli.
  • Juga, http://msdn.microsoft.com/en-us/library/hh977022.aspx daftar _mm256_setr_epi64x di antara intrinsik yang tersedia.

Bantuan apa pun akan sangat dihargai.


4
2017-12-02 20:24


asal


Jawaban:


Tampaknya ini mungkin benar-benar menjadi bug yang dikenal - intrinsik AVX tertentu tampaknya tidak tersedia dalam mode 32-bit. Coba bangun untuk 64 bit dan / atau perbarui ke Visual Studio 2013 Pembaruan 2, di mana ini seharusnya sudah diperbaiki.

Atau, jika Anda hanya memiliki satu contoh di atas di mana Anda menggunakan intrinsik ini, maka Anda dapat mengubah fungsi Anda menjadi:

__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);
}

atau mungkin bahkan:

__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);
}

yang mungkin sedikit lebih efisien.


3
2017-12-02 21:14



Dalam mode 32-bit MSVC tidak mendukung

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

Dalam kasus Anda dalam mode 32-bit Anda dapat melakukan ini:

    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
2017-12-03 08:53