Есть ли какое-либо различие между логическим SSE intrinsics для различных типов? Например, если мы берем ИЛИ операция, существует три intrinsics: _mm_or_ps, _mm_or_pd и _mm_or_si128, все из которых делают то же самое: вычислите битовое "ИЛИ" их операндов. Мои вопросы:
Есть ли любое различие между использованием того или другого внутреннего (с соответствующим преобразованием типа). Разве какие-либо скрытые затраты как более длительное выполнение в некоторой определенной ситуации там не будут?
Эти intrinsics отображаются на три различных x86 инструкции (por, orps, orpd). У кого-либо есть какие-либо идеи, почему Intel тратит впустую драгоценное пространство кода операции для нескольких инструкций, которые делают то же самое?
Я думаю, что все три фактически одинаковы, то есть 128-битные побитовые операции. Причина существования различных форм, вероятно, историческая, но я не уверен. Я предполагаю, что возможно , что в версиях с плавающей запятой может быть какое-то дополнительное поведение, например когда есть NaN, но это чистая догадка. Для обычных входов инструкции кажутся взаимозаменяемыми, например
#include <stdio.h>
#include <emmintrin.h>
#include <pmmintrin.h>
#include <xmmintrin.h>
int main(void)
{
__m128i a = _mm_set1_epi32(1);
__m128i b = _mm_set1_epi32(2);
__m128i c = _mm_or_si128(a, b);
__m128 x = _mm_set1_ps(1.25f);
__m128 y = _mm_set1_ps(1.5f);
__m128 z = _mm_or_ps(x, y);
printf("a = %vld, b = %vld, c = %vld\n", a, b, c);
printf("x = %vf, y = %vf, z = %vf\n", x, y, z);
c = (__m128i)_mm_or_ps((__m128)a, (__m128)b);
z = (__m128)_mm_or_si128((__m128i)x, (__m128i)y);
printf("a = %vld, b = %vld, c = %vld\n", a, b, c);
printf("x = %vf, y = %vf, z = %vf\n", x, y, z);
return 0;
}
$ gcc -Wall -msse3 por.c -o por
$ ./por
a = 1 1 1 1, b = 2 2 2 2, c = 3 3 3 3
x = 1.250000 1.250000 1.250000 1.250000, y = 1.500000 1.500000 1.500000 1.500000, z = 1.750000 1.750000 1.750000 1.750000
a = 1 1 1 1, b = 2 2 2 2, c = 3 3 3 3
x = 1.250000 1.250000 1.250000 1.250000, y = 1.500000 1.500000 1.500000 1.500000, z = 1.750000 1.750000 1.750000 1.750000
В соответствии с рекомендациями Intel и AMD по оптимизации смешивание типов операций с типами данных приводит к снижению производительности, поскольку ЦП внутренне маркирует 64-битные половины регистра для определенного типа данных. Похоже, что это в основном влияет на конвейерную обработку, поскольку инструкция декодируется и запланированы мопы. Функционально они дают одинаковый результат. Новые версии для целочисленных типов данных имеют более крупную кодировку и занимают больше места в сегменте кода. Поэтому, если размер кода является проблемой, используйте старые операции, поскольку они имеют меньшую кодировку.