Средства оптимизации GNAT, используемые в исходном тексте
Существует несколько директив компилятора, которые позволяют изменять размер и скорость выполнения программы:
pragma Pack( Aggregate ); | - | Использовать минимальный размер пространства для агрегата. | |
pragma Optimize( Space / Time / Off ); | - | Выбор типа оптимизации инструкций. | |
pragma Inline( Subprogram ); pragma Inline_Always( Subprogram ); | - | Указывают на необходимость выполнения встроенной подстановки (inline) подпрограммы Subprogram. | |
pragma Discard_Names( type ); | - | Не помещать ASCII-идентификаторы в результирующий исполняемый файл. |
Директива Pack позволяет упаковывать массивы, записи и тэговые записи, что позволяет им, в результате, занимать меньшее пространство.
Например, упакованный массив переменных логического типа Boolean
приводит к тому, что каждая переменная занимает всего один бит.
Директива Pack позволяет упаковывать только структуры данных.
Следует также учесть, что не каждый самостоятельный элемент структуры данных может быть упакован.
Например, если имеется массив записей, то для того чтобы при распределении пространства использовался минимально возможный размер, понадобиться выполнить как упаковку массива, так и упаковку записи.
Также следует учитывать, что упаковка структур данных, как правило, ухудшают скорость выполнения программы.
Примером использования этой директивы компилятора для упаковки записи может служить следующее:
type CustomerProfile is
record Preferred : Boolean; Preorders_Allowed : Boolean; Sales_To_Date : Float; end record; pragma Pack( CustomerProfile ); |
Следует заметить, что GNAT способен выполнять достаточно плотную упаковку, упаковывая отдельные компоненты структур вплоть до индивидуальных битов.
Директива компилятора Optimize позволяет указать компилятору требуемый тип оптимизации инструкций: для максимально возможной скорости выполнения инструкций (Time), для использования инструкциями минимально возможного размера (Space) или без выполнения какой-либо оптимизации вообще (Off).
Эта директива никак не воздействует на структуры данных.
pragma Optimize ( Space ); package body AccountsPayable is |
Это значит, что в местах вызова указанной подпрограммы вместо генерации вызова подпрограммы выполняется непосредственная вставка машинного кода подпрограммы, что позволяет несколько повысить скорость выполнения подпрограммы.
При этом следует учитывать, что использование этой директивы может привести к увеличению общего размера результирующего исполняемого файла, поэтому ее следует использовать для тех подпрограмм, которые имеют маленький размер.
procedure Increment( X : in out Integer ) is begin X := X + 1; end Increment; pragma Inline( Increment ); |
будет проигнорирована, если при компиляции программы не используется опция командной строки компилятора -O3.
Также следует учесть, что опция -O3
будет автоматически осуществлять встроенную вставку коротких подпрограмм.
Директива компилятора Inline_Always вызывает принудительную встроенную вставку подпрограмм, описанных в разных пакетах (подобно опции -gnatn) не зависимо от указания в командной строке компилятора опций -gnatn или -gnatN.
Директива компилятора Discard_Names позволяет освободить пространство занимаемое ASCII-строками имен идентификаторов.
Например, при наличии большого перечислимого типа, Ада обычно сохраняет строки имен для каждого идентификатора значения перечислимого типа.
Это выполняется для поддержки использования атрибута 'Img.
Если использование атрибута 'Img не планируется, то можно указать компилятору на необходимость очистки этих имен.
type Dog_Breed is (Unknown, Boxer, Shepherd, Mixed_Breed); pragma Discard_Names( Dog_Breed ); |
В этом случае, вместо возвращения строкового представления имени идентификатора, атрибут 'Img будет возвращать позицию значения в списке перечисления значений перечислимого типа (например, 0, 1, 2 и так далее).