Скорость регистра MMX против стека для целочисленного хранения без знака - PullRequest
0 голосов
/ 08 декабря 2018

Я рассматриваю реализацию SHA3 в чистой сборке.SHA3 ​​имеет внутреннее состояние 17 64-битных целых чисел без знака, но из-за преобразований, которые он использует, наилучший случай мог бы быть достигнут, если бы у меня было 44 таких целых числа, доступных в регистрах.Плюс один скретч-регистр возможно.В таком случае я мог бы выполнить полное преобразование в регистрах.

Но это нереально, и оптимизация возможна вплоть до нескольких регистров.Тем не менее, чем больше, тем лучше, в зависимости от ответа на этот вопрос.

Я думаю об использовании регистров MMX по крайней мере для быстрого хранения, даже если мне нужно будет переключиться на другие регистры для вычислений.Но я обеспокоен тем, что это древняя архитектура.

Будет ли передача данных между регистром MMX и, скажем, RAX быстрее, чем индексирование u64 в стеке и доступ к ним из того, что, вероятно, будет кешем L1?Или даже если так, есть ли скрытые подводные камни, помимо соображений скорости, за которыми я должен следить?Меня интересует общий случай, поэтому, даже если один из них был быстрее, чем другой на моем компьютере, он все равно может быть неубедительным.

1 Ответ

0 голосов
/ 08 декабря 2018

Использование регистров ymm в качестве «хранилища памяти» - это не выигрыш для производительности.MMX тоже не будет.Этот вариант использования полностью исключает доступ к памяти, который может нарушить микропроцессор.

Эффективная пересылка из хранилища и быстрые обращения к кэш-памяти L1d делают использование обычной оперативной памяти очень хорошим.x86 допускает операнды памяти, такие как add eax, [rdi], и современные процессоры могут декодировать это в один моп.

В MMX вам понадобится 2 мопа, как movd edx, mm0 / add eax, edx.Так что это больше мопсов и больше задержек.movd или movq задержка в / из регистров MMX или XMM хуже, чем задержка пересылки при хранении от 3 до 5 циклов на типичных современных процессорах.


Но если вам не нужночтобы часто перемещать данные назад и вперед, вы могли бы с пользой хранить некоторые данные в регистрах MMX / XMM и использовать pxor mm0, mm1 и т. д.

Если вы можете запланировать свой алгоритм так, чтобы выиметь меньше общих инструкций / мопов от использования movd/movq (int <-> XMM или int <-> MMX) и movq2dq / movdq2q (MMX-> XMM / XMM-> MMX) инструкций вместо хранилищ и операндов памятиили загружается, тогда это может быть победой.

Но на Intel до Haswell есть только 3 исполнительных порта ALU, поэтому суперскалярный конвейер шириной 4 может столкнуться с более узким узким местом (пропускная способность ALU), чем интерфейсныйпропускной способности, если вы оставляете порты хранилища / загрузки бездействующими.

(см. https://agner.org/optimize/ и другие ссылки на производительность в вики-теге x86 .)

...