Эта таблица, вероятно, будет неверно предсказана в первый раз. После этого это может или не может, в зависимости от модели и силы косвенного предсказателя ветвления.

отрим следующий цикл в x86:

; on entry, rdi has the number of iterations
.top:
; some magic happens here to calculate a result in rax
mov [array + rdi * 8], rax ; store result in output array
dec rdi
jnz .top

Это просто: что-то вычисляет результат вrax (не показано), а затем мы сохраняем результат в массив, в обратном порядке, как мы индексируем сrdi.

Я хотел бы преобразовать вышеуказанный цикл, чтобы не делать никаких записей в память (можно предположить, что не показанные вычисления не записывают в память).

Пока цикл считается вrdi ограничено, я мог бы использовать достаточно места (512 байт), предоставленногоymm regs для сохранения значений вместо этого, но на самом деле это неудобно, поскольку вы не можете «проиндексировать» произвольный регистр.

Один из подходов состоит в том, чтобы всегда перетасовывать весь «массив»ymm регистрируется одним элементом, а затем вставляет элемент во вновь освобожденную позицию вверх.

Что-то вроде этого:

vpermq  ymm3, ymm3, 10_01_00_11b ; left rotate ymm by qword
vpermq  ymm2, ymm2, 10_01_00_11b ; left rotate ymm by qword
vpermq  ymm1, ymm1, 10_01_00_11b ; left rotate ymm by qword
vpermq  ymm0, ymm0, 10_01_00_11b ; left rotate ymm by qword

vblenddd ymm3, ymm3, ymm2, 3     ; promote one qword of ymm2 to ymm3
vblenddd ymm2, ymm2, ymm1, 3     ; promote one qword of ymm1 to ymm2
vblenddd ymm1, ymm1, ymm0, 3     ; promote one qword of ymm0 to ymm1

pinsrq   xmm0, rax, 0  ; playing with mixed-VEX mode fire (see Peter's answer)

Это показывает обработку только четырех из 16 регистров, так что, очевидно, для выполнения всех 16 будет много кода (32 инструкции).

Есть ли способ лучше?

Непредсказуемые ветки нежелательны, но мы все еще можем рассмотреть решения, которые их используют.

Ответы на вопрос(2)

Ваш ответ на вопрос