Признаки MMX, такие как _mm_cvtpd_pi32, не найдены с MSV C 2019 для 64-битных целей; изменить с 2013 года? - PullRequest
3 голосов
/ 30 марта 2020

В настоящее время я работаю над обновлением большой кодовой базы с VS2013 до VS2019. Одна из ошибок компилятора, с которыми я столкнулся, выглядит следующим образом:

intrinsics.h (348): ошибка C3861: '_mm_cvtpd_pi32': идентификатор не найден

This Функция intrinsi c определена в emmintrin.h в Visual Studio. Я получаю эту ошибку только при нацеливании на 64-битные сборки. При ближайшем рассмотрении вы увидите, что в период между 2013 и 2019 годами определение emmintrin.h было изменено с:

extern __m64 _mm_cvtpd_pi32(__m128d _A);
extern __m64 _mm_cvttpd_pi32(__m128d _A);
extern __m128d _mm_cvtpi32_pd(__m64 _A);

На это:

#if defined(_M_IX86)
extern __m64 _mm_cvtpd_pi32(__m128d _A);
extern __m64 _mm_cvttpd_pi32(__m128d _A);
extern __m128d _mm_cvtpi32_pd(__m64 _A);
#endif

ie: директива препроцессора гарантирует, что функции теперь доступны только для 32-битных целей. Сторонний заголовочный файл, из которого происходит ошибка, использует эти функции независимо от цели (64-битная или 32-битная). Предположительно, лучший способ действий здесь - это отредактировать этот заголовочный файл, чтобы эта функция вызывалась только для 32-битных целей. Однако, что мне более интересно, почему это было изменено с 2013 по 2019 год? Я вижу описание этой функции здесь:

https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text = _ mm_cvtpd_pi32 & expand = 1705

Разве она никогда не применялась для 64-битных целей с самого начала? Или он был заменен 64-битной версией, которую мне нужно рассмотреть?

1 Ответ

2 голосов
/ 30 марта 2020

Я не знаю, есть ли способ заставить MSV C 2019 скомпилировать это устаревшее встроенное MMX c.

Безопасно использовать инструкции MMX в 64-битном коде на Windows, но MS не облегчает создание такого кода с использованием компиляторов MS. Intrinsi c может не поддерживаться более новым MSVC; используйте лучший компилятор (например, clang) , если вам нужно скомпилировать старый код с внутренними компонентами MMX, если нет обходного пути для MSV C.

(в начале истории x86-64 и 64-битный Windows, тот факт, что MS удалила некоторую поддержку MMX компилятора или ассемблера, заставил некоторых беспокоиться о том, что, возможно, ядро ​​Windows не будет правильно выполнять переключение контекста для состояния x87 / MMX. Это сомнение было необоснованным. Если вы можете получить код MMX для компиляции / сборки, например, с помощью других инструментов, он все равно будет работать безупречно. Windows поддерживает его, а процессоры x86-64 в длинном режиме по-прежнему полностью поддерживают MMX. Я не использую Windows и я точно не помню, какая именно поддержка MMX была удалена.)


Конечно, обычно лучше использовать SSE2 вместо MMX , то есть функции epi32 вместо pi32 (или любой другой целочисленной ширины элемента). SSE2 является базовой для x86-64, а также требуется для SIMD двойной точности (включая intrinsi c) этого преобразования.

Вариант использования для этого преобразования (я думаю) главным образом для получения целочисленных векторов MMX для использования с существующим унаследованным MMX-векторизованным кодом.

Но в этом конкретном случае c cvtpd2pi на самом деле не медленнее, чем cvtpd2qd (обычный SSE2 _mm_cvtpd_epi32) - оба - 2 моп, я думать, потому что даже в домене регистра XMM он должен перетасовать 32-битные целые числа в нижнюю часть. https://www.uops.info/table.html. В отличие от версии ps, в которой преобразование FP-> int между регистрами XMM выполняется по одной операции.

MMX имеют более низкую пропускную способность, чем эквивалентные инструкции SSE2 / 3 для недавних процессоров (работающих на меньшем количестве портов), и mov устранение не работает на них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...