Ориентиры - это простая библиотека профилирования для OCAML. Он предоставляет примитивы для разграничения участков кода и измерения производительности инструментального кода во время выполнения. Доступные меры получаются путем агрегирования циклов ЦП (с использованием счетчика марки ЦП), применения времени (с использованием Sys.time
) и выделенных байтов (с Gc.allocated_bytes
). Инструментария кода может выполняться вручную автоматически или полуавтоматически, используя расширение PPX.
Во время выполнения вашей программы обход инструментального кода по потоку управления записывается как «вызовочный граф», который несет собранные меры. Результаты могут быть просмотрены либо непосредственно на консоли, либо экспортированы в JSON.
Этот инструмент предназначен для использования в качестве способа найти, где время потрачено в ваших программах (и не сравнивает независимые части кода, такие как core_bench), предоставляя результаты, которые соответствуют только инструментальной части вашего кода OCAML (вопреки инструментам, которые непосредственно работайте с бинарным исполняемым файлом, таким как GPROF или PERF).
Для получения дополнительной информации вы можете просмотреть API.
Библиотека разделена на два пакета: landmarks
для библиотеки времени выполнения и landmarks-ppx
для реализации автоматического инструментария препроцессора.
opam install landmarks
или
opam install landmarks-ppx
Установит либо библиотеку времени выполнения, либо библиотеку времени выполнения и препроцессор.
git clone https://github.com/LexiFi/landmarks.git
cd landmarks
dune build @install
Просто используйте landmarks
библиотеки и препроцессорные landmarks-ppx
чтобы сравнить ваши исполняемые файлы и библиотеки. Например, следующий файл dune
создает исполняемый test
используя библиотеку landmarks
и его PPX. Необязательный флаг --auto
включает автоматическую инструментацию (см. Ниже).
(executable
(name test)
(libraries landmarks)
(preprocess (pps landmarks-ppx --auto))
)
Можно использовать дюну для автоматического запуска инструментария проекта. Посмотрите на Lexifi/Landmarks-Starter для базового примера и просмотрите Руководство Dune для получения дополнительной информации.
ocamlfind ocamlopt -c -package landmarks prog.ml
ocamlfind ocamlopt -o prog -package landmarks -linkpkg prog.cmx
Вы можете заменить «ocamlopt» на «OCAMLC», чтобы скомпилировать программу в байт -коде.
ocamlfind ocamlopt -c -package landmarks -package landmarks-ppx -ppxopt landmarks-ppx,--auto prog.ml
ocamlfind ocamlopt -o prog -package landmarks -linkpkg prog.cmx
Обратите внимание, что «-ppxopt Landmarks-ppx,-Auto» является необязательным и включает автоматическую инструментацию.
Есть три основных примитива:
val register : string -> landmark
val enter : landmark -> unit
val exit : landmark -> unit
Функция register
объявляет о новых достопримечательностях и должна использоваться в Toplevel. Функции enter
и exit
используются для разграничения части кода, прикрепленной к ориентиру. В конце профилирования мы получаем для каждого знакомых, потраченной информации, потраченной на выполнение соответствующего куска кода. Во время исполнения следы каждого посещаемого достопримечательности также зафиксированы, чтобы построить «Callgraph».
Например:
open Landmark
let loop = register " loop "
let sleep = register " sleep "
let main = register " main "
let zzz () =
enter sleep;
Unix. sleep 1 ;
exit sleep
let () =
begin
start_profiling () ;
enter main;
enter loop;
for _ = 1 to 9 do
zzz ()
done ;
exit loop;
zzz () ;
exit main;
end
(Этот файл может быть скомпилирован с ocamlfind ocamlc -o prog -package landmarks -package unix -linkpkg prog.ml
)
Индуцированный Callgraph есть:
- 100.00% : main
| - 90.00% : loop
| | - 100.00% : sleep
| - 10.00% : sleep
который может быть перефразируется как:
clock()
Библиотека обеспечивает связывание с высокопроизводительным счетчиком циклов для архитектур x86 32 и 64 битов (обратите внимание, что вы можете использовать landmarks-noc.cm(x)a
архив для обеспечения собственной реализации). Он используется для измерения времени, проведенного внутри инструментального кода.
Чтобы избежать написания кода шаблона, вы можете использовать расширение PPX, распространяемое с помощью этого пакета. Это позволяет программисту выражать приборные выражения с использованием аннотации и автоматически инструментировать функции верхнего уровня.
Значение expr [@landmark "name"]
расширяется в
Landmark. enter __generated_landmark_1;
let r =
try expr with e -> Landmark. exit __generated_landmark_1; raise e
in
Landmark. exit __generated_landmark_1;
r
и декларация
let __generated_landmark_1 = Landmark. register " name "
добавляется на верхнем уровне.
Следует отметить, что это преобразование не сохраняет хвостовые рекурсивные вызовы (а также не предотвращает некоторое обобщение полиморфизма). Чтобы обойти эти проблемы, рекомендуется использовать другое предоставленное расширение вокруг let ... in
и let rec ... in
:
let [ @ landmark] f = body
который расширен в:
let __generated_landmark_2 = Landmark. register " f "
let f = body
let f x1 ... xn =
Landmark. enter __generated_landmark_2;
let r =
try f x1 ... xn with e -> Landmark. exit __generated_landmark_2; raise e
in
Landmark. exit __generated_landmark_2;
r
Когда Arity n
of f
получается путем подсчета мелких случаев fun ... ->
и function ... ->
в body
. Обратите внимание, что при использовании этой аннотации с помощью привязки let-rec будут записаны только вызовы в записи. Например, в следующем фрагменте кода
let () =
let [ @ landmark] rec even n = (n = 0 ) || odd (n - 1 )
and [ @ landmark] odd n = (n = 1 ) || n > 0 && even (n - 1 )
in Printf. printf " 'six is even' is %b n " (even 6 )
Ориентир, связанный с «даже», будет пройден ровно один раз (и не три раза!), А то, что поток управления не пройдет через ориентир, связанный с «нечетным».
Структурные аннотации [@@@landmark "auto"]
и [@@@landmark "auto-off"]
активируют или деактивируют автоматическую инструментацию функций верхнего уровня в модуле. В автоматическом режиме все объявления функций неявно аннотированы. Автоматическое приборы может быть включено/отключено для всех файлов через опцию auto
в OCAML_LANDMARKS
, как подробно описано ниже.
Переменная среда OCAML_LANDMARKS
читается на двух разных этапах: когда выполняется перезапись PPX, и когда модуль достопримечательностей загружается инструментальной программой. Эта переменная проанализирована как разделенный запятой список элементов option=argument
или option
, где option
:
Во время стадии переписывания PPX (во время компиляции):
auto
(без аргументов): по умолчанию включает автоматическую инструментацию (ведет себя так, как будто каждый модуль начинается с аннотации [@@@landmark "auto"]
).
threads
(без аргументов): сообщает расширению PPX использовать модуль Landmark_threads
вместо Landmark
.
При загрузке инструментальной программы (во время выполнения):
format
с возможными аргументами: textual
(по умолчанию) или json
. Он контролирует выходной формат профилирования, который является либо консольным представлением, либо кодированием Callgraph JSON.
threshold
с числом от 0,0 до 100,0 в качестве аргумента (по умолчанию: 1,0). Если порог не равен нулю, текстовый вывод будет скрывать узлы в вызове ниже этого порога (в процентах от времени их родителя). Этот вариант не имеет смысла для других форматов.
output
с возможным аргументом: stderr
(по умолчанию), stdout
, temporary
, <file>
(где <file>
- путь файла). Он говорит, где вывести результаты профилирования. С temporary
он распечатает его во временном файле (имя этого файла будет напечатано при стандартной ошибке). Вы также можете использовать temporary:<directory>
для указания каталога, в котором генерируются файлы.
debug
без аргументов. Активирует многословный режим, который выводит трассы на STDERR каждый раз, когда называются примитивы достопримечательностей.
time
без аргумента. Также собирайте Sys.time
TimeStass во время профилирования.
без off
. Отключить профилирование.
on
никаких аргументах. Включить профилирование (по умолчанию; может быть опущено).
allocation
без аргумента. Также собирайте данные Gc.allocated_byte
.
Вы можете либо собрать веб -просмотр, либо просмотреть его в Интернете. Вам нужно загрузить файлы JSON, используя FilePicker, а затем вы можете нажать, чтобы просмотреть график вызовов.
Модуль Landmark
не защищен потоком. Если у вас есть несколько потоков, вы должны убедиться, что не более одного потока выполняет инструментальный код. Для этого вы можете использовать модуль Landmark_threads
(включенный в ориентиры-threads.cm (x) архив), который предотвращает выполнять функции, не защищенные потоком, выполнять во всех потоках, но тот, который начал профилирование.
Аннотация на выражениях может выравниваться с полиморфизмом (это не относится к аннотации let-связывания). Например, следующий кусок кода не сможет скомпилировать:
let test = ( fun x -> x)[ @ landmark " test " ]
in test " string " , test 1
Этот пакет «достопримечательности» лицензирован Lexifi в соответствии с условиями лицензии MIT.
Контакт: [email protected]