Расширенные векторные расширения Intel (AVX) не предлагают продукт dot в 256-битной версии (регистр YMM) для переменных с плавающей запятой с двойной точностью. "Почему?" вопрос был очень кратко рассмотрен на другом форуме (здесь) и на Qaru (here). Но вопрос, с которым я столкнулся, заключается в том, как эффективно заменить эту отсутствующую инструкцию другими инструкциями AVX?
Точечный продукт в 256-битной версии существует для переменных с плавающей запятой с одной точностью (ссылка здесь):
__m256 _mm256_dp_ps(__m256 m1, __m256 m2, const int mask);
Идея состоит в том, чтобы найти эффективный эквивалент этой отсутствующей инструкции:
__m256d _mm256_dp_pd(__m256d m1, __m256d m2, const int mask);
Чтобы быть более конкретным, код, который я хотел бы преобразовать из __m128
(четыре поплавка) в __m256d
(4 удваивается), использует следующие инструкции:
__m128 val0 = ...; // Four float values
__m128 val1 = ...; //
__m128 val2 = ...; //
__m128 val3 = ...; //
__m128 val4 = ...; //
__m128 res = _mm_or_ps( _mm_dp_ps(val1, val0, 0xF1),
_mm_or_ps( _mm_dp_ps(val2, val0, 0xF2),
_mm_or_ps( _mm_dp_ps(val3, val0, 0xF4),
_mm_dp_ps(val4, val0, 0xF8) )));
Результатом этого кода является вектор _m128
четырех поплавков, содержащий результаты точечных произведений между val1
и val0
, val2
и val0
, val3
и val0
, val4
и val0
.
Может быть, это может дать подсказки для предложений?