Как сохранить более низкие или более высокие значения из регистра AVX / AVX2 (YMM) в память, как это делает SSE movlps / movhps?

Существуют ли какие-либо инструкции, которые могут сохранять более низкие или более высокие значения из 256-битного регистра AVX / AVX2 (YMM) в адрес памяти, как это делает инструкция SSE movlps / movhps?

Или есть другой способ реализовать это?

Любая помощь будет оценена, спасибо!


person Sean Yang    schedule 30.01.2013    source источник
comment
Вы можете использовать инструкции по вставке / извлечению. Те переведут их в другой регистр. Так что вам все равно понадобится отдельная инструкция по загрузке / сохранению. Но, тем не менее, это ничем не отличается от простого использования 128-битной перестановки для обмена двумя половинами.   -  person Mysticial    schedule 30.01.2013
comment
Спасибо @Mysticial! Я обнаружил, что AVX2 vextractf128 может сработать для этого.   -  person Sean Yang    schedule 04.02.2013


Ответы (1)


Сохраните low128 с vmovdqu [rdi], xmm0.

Сохраните high128 с VEXTRACTI128 xmm1/m128, ymm2, 1. Вероятно, вы можете заставить компилятор сгенерировать хранилище в памяти, присвоив результат внутреннего извлечения ссылке в памяти.

vextracti128 / f128 занимает 2 мопа, даже в объединенном домене (Haswell), так что IDK имеет смысл кодировать его с непосредственным операндом 0. (до AVX512, когда непосредственный индекс вместо movh становится актуальным, поскольку они не знали, что собираются заменить VEX на EVEX для AVX512). Нет никакого штрафа за смешивание AVX2 с регистрами xmm и AVX2 с регистрами ymm, поэтому вы можете просто использовать 128-битное хранилище версии xmm, чтобы получить низкий 128, точно так же, как вы можете получить low32 для 64-битного регистра GP, указав eax вместо rax.

При использовании встроенных функций, вероятно, раздражает приведение чего-либо, поэтому, если повезет, компилятор скомпилирует _mm256_extracti128_si256 (vec, 0) в vmovdqu соответствующего xmm reg. Но если ваш компилятор этого не сделает, ваш код будет быстрее, если вы заставите его генерировать vmovdqu. (movdqu работает так же быстро, как vmovdqa, если адрес выровнен, точно так же, как доступ к памяти AVX без использования mov.)

person Peter Cordes    schedule 08.06.2015
comment
Еще одно решение - vmovaps XMMWORD PTR [rdi], xmm0 для нижней части 128. GCC / clang компилирует _mm_store_ps(ptr, _mm256_castps256_ps128(v)) для Haswell и выше. - person plasmacel; 15.12.2016
comment
@plasmacel: ЦП не имеет штрафов за задержку обхода для хранения, поэтому movups / movaps сохраните байт машинного кода в устаревшей кодировке SSE (не VEX). Хотя нет смысла отдавать предпочтение vmovaps перед vmovdqa, но и недостатков нет, так что я предполагаю, что это упрощает код gcc - всегда использовать ...ps хранилищ. - person Peter Cordes; 15.12.2016