Вы писали "чтобы исключить операции пересылки текущего значения остатка, основной цикл алгоритма пришлось развернуть", то есть получилось два блока, а посередине условный выход.
Если удалить второй блок, то код будет выглядеть примерно так:
@next:
mov edx, eax
[БЛОК]
add ecx, 8
jle @next
При этом скорость не уменьшится, а даже увеличится, за счёт уменьшения числа ветвлений. Если код будет вызываться каждый раз с разным размером буфера, то мы уменьшаем вероятность "branch mispredition penalty", и упрощам код, что позволяет процессору легче спрогнозировать окончание цикла. Для простых циклов процессоры, такие как Skylake, c MacroOp fusion, прогнозирует его окончание удивительно хорошо.
развёрнутый код (два блока а посередине условный выход)
Вы писали "чтобы исключить операции пересылки текущего значения остатка, основной цикл алгоритма пришлось развернуть", то есть получилось два блока, а посередине условный выход.
Вы привели код по такой схеме:
Если удалить второй блок, то код будет выглядеть примерно так:
При этом скорость не уменьшится, а даже увеличится, за счёт уменьшения числа ветвлений. Если код будет вызываться каждый раз с разным размером буфера, то мы уменьшаем вероятность "branch mispredition penalty", и упрощам код, что позволяет процессору легче спрогнозировать окончание цикла. Для простых циклов процессоры, такие как Skylake, c MacroOp fusion, прогнозирует его окончание удивительно хорошо.