cmpsd
- это инструкция, которая существует в asm и работает с регистрами XMM, поэтому было бы непоследовательным , а не , чтобы выставить ее с помощью встроенных функций.
(Почти все инструкции упакованных FP (кроме shuffles / blends) имеют скалярную версию, поэтому снова есть аргумент согласованности для дизайна ISA, это просто дополнительный префикс к тому же коду операции, и может потребоваться больше транзисторов для специального случая, чем коду операции не поддержка скалярной версии.)
Могли бы вы или люди, разрабатывающие встроенный API, придумать разумный вариант использования, совсем не в этом дело. Было бы глупо оставлять вещи на этой основе;когда кто-то придумывает сценарий использования, ему придется использовать встроенный asm или написать C, который компилирует больше инструкций.
Возможно, кто-нибудь когда-нибудь найдет сценарий использования для вектора с маской в качестве минимумаполовина, и все еще действующий double
в высокой половине.например, может _mm_and_ps
вернуться на вход для условного обнуления только нижнего элемента без необходимости упакованного сравнения в верхнем элементе для получения значения true.
Или учтите, что все единицы - этобитовый шаблон для NaN, а все ноль - это битовый шаблон для +0.0
.
IIRC, cmppd
замедляется, если какой-либо из элементов является ненормальным (если у вас нетбит DAZ, установленный в MXCSR).По крайней мере, на некоторых старых процессорах, которые существовали во время разработки ISA.Таким образом, для сравнения FP наличие скалярных версий является (или было) необходимым для избежания ложных вспомогательных операций FP для элементов, которые вам не нужны.
Также для избежания ложных исключений FP (или установка исключенияфлагы, если они замаскированы), например, если есть NaN в верхнем элементе любого вектора.
@ wim также хорошо показывает, что процессоры Intel до того, как Core2 декодировал 128-битные инструкции SIMD в 2 мопа, одиндля каждой 64-битной половины.Поэтому использование cmppd
, когда вам не нужен высокий половинный результат, всегда будет медленнее, даже если оно не может быть ошибочным.Множество многопользовательских инструкций могут легко стать узким местом для декодеров переднего плана на процессорах без кэш-памяти uop, потому что только один из декодеров может их обрабатывать.
Обычно вы не используете встроенные функции для FPскалярные инструкции типа cmpsd
или addsd
, но они существуют в том случае, если вы хотите их (например, как последний шаг в горизонтальной сумме).Чаще всего вы просто предоставляете компилятору использовать скалярные версии инструкций при компиляции скалярного кода без автоматической векторизации.
И часто для скалярных сравнений компиляторы будут нуждаться в результате в EFLAGS, поэтому вместо них будут использовать ucomisd
создания маски сравнения, но для кода без ответвлений маска часто полезна, например, для a < b ? c : 0.0
с cmpsd
и andpd
.(Или действительно andps
, потому что он короче и делает то же самое, что и бессмысленный andpd
.)