Vxorps-обнуление AMD Jaguar/Bulldozer / Zen быстрее с регистрами xmm, чем ymm?

процессоры AMD обрабатывают инструкции 256B AVX путем декодирования в две операции 128b. например,vaddps ymm0, ymm1,ymm1 на AMD паровой каток декодирует до 2 макро-ops, с половиной пропускной способности vaddps xmm0, xmm1,xmm1.

XOR-обнуление является частным случаем (нет входной зависимости и на Jaguar по крайней мере избегает потребления физической записи файла регистра, и позволяет movdqa из этого реестра устраняться при выпуске / переименовании, как бульдозер делает все время даже для ненулевых регов). но это обнаружен достаточно рано, что vxorps ymm0,ymm0,ymm0 все еще только декодирует до 1 макро-op с равной производительностью до vxorps xmm0,xmm0,xmm0? (в отличие от vxorps ymm3, ymm2,ymm1)

или обнаружение независимости происходит позже, после уже декодирования в два uops? Кроме того, vector xor-zeroing на процессорах AMD все еще использует порт выполнения? На Intel-процессорах Nehalem нужен порт, но Sandybridge-family обрабатывает его на этапе выпуска/переименования.

таблицы инструкций Агнера Фога не перечисляют этот особый случай, и его руководство microarch не упоминает количество uops.


это может означать vxorps xmm0,xmm0,xmm0 это лучший способ реализовать _mm256_setzero_ps().

для AVX512,_mm512_setzero_ps() также сохраняет байт, используя только идиому обнуления VEX, а не EVEX, когда это возможно. (т. е. для zmm0-15. vxorps xmm31,xmm31,xmm31 все равно потребуется EVEX). gcc / clang в настоящее время используют идиомы XOR-zeroing любой ширины регистра, которую они хотят, а не всегда используют AVX-128.

сообщается как clang 32862 ошибка и gcc ошибка 80636. MSVC уже использует xmm. Пока не сообщается ICC, который также использует ZMM regs для обнуления AVX512. (Хотя Intel может не захотеть меняться, поскольку в настоящее время нет никаких преимуществ на любых процессорах Intel, только AMD. Если они когда-нибудь выпустят маломощный процессор, который делит векторы пополам, они могут. Их текущий маломощный deisgn (Silvermont) не поддерживает AVX вообще, только SSE4.)


единственный возможный недостаток, который я знаю использование инструкции AVX-128 для обнуления регистра 256b заключается в том, что она не запускает прогрев блоков выполнения 256b на процессорах Intel. Возможно, победив Хак C или C++, который пытается их разогреть.

(256b векторные инструкции медленнее для первых ~ 56k циклов после первой инструкции 256b. См. раздел Skylake в файле microarch pdf Agner Fog). Это, вероятно, нормально, если вызов noinline функция, которая возвращает _mm256_setzero_ps не является надежным способом разогреть исполнение единицы. (Тот, который все еще работает без AVX2 и избегает любых нагрузок (которые могут пропустить кэш), - это __m128 onebits = _mm_castsi128_ps(_mm_set1_epi8(0xff));
return _mm256_insertf128_ps(_mm256_castps128_ps256(onebits), onebits), который должен составить к pcmpeqd xmm0,xmm0,xmm0 / vinsertf128 ymm0,xmm0,1. Это все еще довольно тривиально для того, что вы вызываете один раз, чтобы разогреть (или согреть) исполнительные единицы намного раньше критического цикла. И если вы хотите что-то, что может быть встроенным, вам, вероятно, нужен inline-asm.)


у меня нет оборудования AMD, поэтому я не могу проверить это.

если у кого-то есть оборудование AMD но не знает, как тестировать, использовать счетчики perf для подсчета циклов (и предпочтительно m-ops или uops или как их называет AMD).

это источник NASM/YASM, который я использую для тестирования коротких последовательностей:

section .text
global _start
_start:

    mov     ecx, 250000000

align 32  ; shouldn't matter, but just in case
.loop:

    dec     ecx  ; prevent macro-fusion by separating this from jnz, to avoid differences on CPUs that can't macro-fuse

%rep 6
    ;    vxorps  xmm1, xmm1, xmm1
    vxorps  ymm1, ymm1, ymm1
%endrep

    jnz .loop

    xor edi,edi
    mov eax,231    ; exit_group(0) on x86-64 Linux
    syscall

если вы не на Linux, возможно, замените материал после цикла (выход syscall) на ret, и вызовите функцию из C

1 ответов


исключающее или вычислить регистрация компании емм, порождает два микрокоманд на Ryzen драмов, а исключающее ИЛИ передоза в XMM-регистр, порождает только один микро-ФП. Поэтому оптимальный способ xeroing регистра ymm в это исключающее или соответствующего регистра XMM с самим собой и полагаться на неявные ноль расширение.

единственный процессор, который поддерживает AVX512 сегодня-Knights Landing. Оно использует одиночное micro-op для xor'ING регистр zmm. Очень распространено обрабатывать новое расширение размера вектора путем расщепления это через два. Это произошло при переходе от 64 до 128 бит и при переходе от 128 до 256 бит. Более чем вероятно, что некоторые процессоры в будущем (от AMD или Intel или любого другого поставщика) разделят 512-битные векторы на два 256-битных вектора или даже четыре 128-битных вектора. Таким образом, оптимальным способом обнуления регистра zmm является xor 128-битный регистр с самим собой и полагаться на нулевое расширение. И вы правы, 128-битная VEX-кодированная инструкция составляет один или два байта укорачиваться.

большинство процессоров распознают, что xor регистра сам по себе не зависит от предыдущего значения регистра.