Оптимальный способ хранения двойных SSE2 / AVX / AVX512 как плавающих с использованием встроенных функций - PullRequest
0 голосов
/ 18 октября 2018

Мне часто нужно использовать double по соображениям точности, но я хочу сохранить результаты как числа с плавающей точкой.Какой оптимальный способ?Сейчас я использую:

SSE2: _mm_store_sd((double*)dst, _mm_castps_pd(_mm_cvtpd_ps(xmm)));

AVX: _mm_storeu_ps(dst, _mm256_cvtpd_ps(ymm));

AVX512: _mm256_storeu_ps(dst, _mm512_cvtpd_ps(zmm));

Есть идеи по улучшению?

1 Ответ

0 голосов
/ 18 октября 2018

Преобразование из упакованного двойного в упакованное плавание доступно только в сужающейся форме, а не в версии, которая принимает 2 вектора двойного и упаковывает в 1 вектор плавания.Так что да, встроенные функции для [v]cvtpd2ps - ваш единственный выбор.Эти инструкции декодируют до 2 мопов на современном Intel;один для порта (ов) FMA и один для порта в случайном порядке.(https://agner.org/optimize/)

Сохранение результата не вызывает затруднений, вам нужна некоторая форма _mm_store/storeu.


Для 128-битных векторов (в результате 2x float = 64битов), у вас нет целого 128-битного вектора результатов. Вы можете перетасовать два вместе в 128-битный вектор, но с пропускной способностью FP, равной 1 за такт на Intel, начиная с Sandybridge, вероятно, лучше всего хранитьони оба по отдельности.

Вы хотите, чтобы movlps вместо movsd сохранял младшие 64 бита вектора float; он сохраняет один байт инструкции, а для встроенной функции C требуется меньше приведения.к сожалению, требуется __m64* вместо float*, поэтому вам все еще нужен один приведение:

_mm_storel_pi((__m64*)dst,   _mm_cvtpd_ps(xmm) );

Но для загрузки вам определенно нужно movsd, чтобы избежать ложной зависимости от старогозначение. movlps загружает слияние в регистр; movsd загружает нулевое расширение. На самом деле, cvtps2pd xmm, qword [mem] позаботится об этом за вас, если вы можете заставить компилятор выдавать его из встроенных функций.

Itможет быть трудно сделать это безопасно, для аналогичныхПричины pmovzxbw xmm, qword [mem]: компиляторам не удается сложить загрузку qword в операнд памяти для pmovzx / sx: ( Загрузка 8 символов из памяти в переменную __m256 в виде упакованных плавающих одинарной точности )

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