Каково различие между логическим SSE intrinsics?

Есть ли какое-либо различие между логическим SSE intrinsics для различных типов? Например, если мы берем ИЛИ операция, существует три intrinsics: _mm_or_ps, _mm_or_pd и _mm_or_si128, все из которых делают то же самое: вычислите битовое "ИЛИ" их операндов. Мои вопросы:

  1. Есть ли любое различие между использованием того или другого внутреннего (с соответствующим преобразованием типа). Разве какие-либо скрытые затраты как более длительное выполнение в некоторой определенной ситуации там не будут?

  2. Эти intrinsics отображаются на три различных x86 инструкции (por, orps, orpd). У кого-либо есть какие-либо идеи, почему Intel тратит впустую драгоценное пространство кода операции для нескольких инструкций, которые делают то же самое?

16
задан Paul R 11 June 2015 в 21:27
поделиться

2 ответа

Я думаю, что все три фактически одинаковы, то есть 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
3
ответ дан 30 November 2019 в 22:02
поделиться

В соответствии с рекомендациями Intel и AMD по оптимизации смешивание типов операций с типами данных приводит к снижению производительности, поскольку ЦП внутренне маркирует 64-битные половины регистра для определенного типа данных. Похоже, что это в основном влияет на конвейерную обработку, поскольку инструкция декодируется и запланированы мопы. Функционально они дают одинаковый результат. Новые версии для целочисленных типов данных имеют более крупную кодировку и занимают больше места в сегменте кода. Поэтому, если размер кода является проблемой, используйте старые операции, поскольку они имеют меньшую кодировку.

7
ответ дан 30 November 2019 в 22:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: