Встроенная подстановка (inline) для кода на встроенном ассемблере
При использовании маленьких функций, затраты на выполнение вызова могут оказаться больше чем затраты на выполнение непосредственного кода функции, которая написана на встроенном ассемблере.
Это хорошо демонстрирует пример функции Increment.
Решением такой проблемы может быть использование встроенной подстановки (inline), которая позволяет в месте вызова подпрограммы (процедуры или функции), написанной на встроенном ассемблере, осуществить непосредственную вставку машинного кода, который соответствует этой подпрограмме.
Таким образом, для выполнения встроенной подстановки показанной ранее функции Increment, необходимо просто добавить соответствующую директиву компилятора:
with Interfaces; use Interfaces; with Ada.Text_IO; use Ada.Text_IO; with System.Machine_Code; use System.Machine_Code;
procedure Inc_It2 is function Increment (Value : Unsigned_32) return Unsigned_32 is Result : Unsigned_32; begin Asm ("incl %0", Inputs => Unsigned_32'Asm_Input ("a", Value), Outputs => Unsigned_32'Asm_Output ("=a", Result)); return Result; end Increment; pragma Inline (Increment); Value : Unsigned_32; begin Value := 5; Put_Line ("Value before is" & Value'Img); Value := Increment (Value); Put_Line ("Value after is" & Value'Img); end Inc_It2; |
После компиляции этой программы с указанием выполнения полной оптимизации (опция -O2) и разрешением осуществления встроенной подстановки (опция -gnatpn) функция Increment будет откомпилирована как обычно, но в том месте, где раньше указывался вызов функции:
pushl %edi call _inc_it__increment.1 |
теперь будет расположен непосредственный код этой функции:
movl %esi,%eax #APP incl %eax #NO_APP movl %eax,%edx |
В конечном итоге, это повысит общую эффективность выполнения кода программы.