Ассемблер - экстремальная оптимизация


Все аргументы в одном месте


При вызове функций по соглашениям cdecl или stdcall, указатель стека постоянно "пляшет", что сбивает с толку процессорный кэш и снижает производительность. При соглашении stdcall от этого никуда не уйдешь, поскольку аргументы очищает непосредственно сама вызываемая функция, но для cdecl-функций кое-что все-таки можно сделать.

Во-первых, как уже говорилось, стек можно балансировать не сразу после выхода из функции, а спустя некоторое время, объединяя несколько команд ADDESP,XXh

в одну (конкретный пример показан в листинге 4). Однако, это не работает с циклами и ветвлениями. Функция, вызываемая в цикле, буквально пожирает память, если только аргументы немедленно не выталкиваются из стека. Но памяти — много и на небольшом количестве итераций с этим еще можно хоть как-то смириться (правда, выигрыша в производительности мы уже не получим, будет просто чудо, если такой объем вообще уместиться в кэше первого уровня).

Ветвления создают еще большую проблему — заставляя нас вводить дополнительные переменные (как правило, регистровые), запоминающие: вызывалась ли функция под ветвлением и если да, то сколько байт стекового пространства "числиться" за ней. Все это усложняет код и сводит на нет в общем-то неплохую идею.

А что если… передавать аргументы через однократно выделенный регион памяти? Это обеспечит максимальную скорость и минимальные потребности в стеке. Мы будем действовать так: на входе в функцию резервируем блок памяти равный наибольшему объему аргументов, передаваемых функции, а затем просто кладем туда аргументы по ходу дела. Регистр ESP уже не "пляшет" и циклы выполняются с предельной скоростью. Единственный минус в том, что передавать аргументы приходится не инструкций PUSH, а более длинной командой MOV [EBP?XXh],YYYY.

Конкретная реализация может выглядеть, например, так:

       PUSH EBP                   ; сохраняем EBP

       MOV EBP,ESP                ; открываем кадр стека

       SUB ESP,10h                ; выделяем память для аргументов



Содержание раздела