Spec-Zone.ru › Julia 1.8

Профилирование

Профилирование процессора

Существует два основных подхода к профилированию кода Julia:

Через @profile

Где профилирование включено для данного вызова с помощью макроса @profile.

julia> using Profile

julia> @profile foo()

julia> Profile.print()
Overhead ╎ [+additional indent] Count File:Line; Function
=========================================================
    ╎147  @Base/client.jl:506; _start()
        ╎ 147  @Base/client.jl:318; exec_options(opts::Base.JLOptions)
...

Вызванное во время выполнения

Задачи, которые уже выполняются, также могут быть профилированы в течение определённого периода времени в любой момент по запросу пользователя.

Для запуска профилирования:

  • MacOS & FreeBSD (платформы на основе BSD): Используйте ctrl-t или передайте сигнал SIGINFO процессу julia, например % kill -INFO $julia_pid.
  • Linux: Передайте сигнал SIGUSR1 процессу julia, например % kill -USR1 $julia_pid.
  • Windows: В настоящее время не поддерживается.

Сначала отображается один стек вызовов в момент броска сигнала, затем собирается профиль длительностью 1 секунда, а затем отчёт о профиле в следующей точке перехода к другому заданию, которая может быть в момент завершения задачи для кода без точек перехода, например, в жёстких циклах.

julia> foo()
##== the user sends a trigger while foo is running ==##
load: 2.53  cmd: julia 88903 running 6.16u 0.97s

======================================================================================
Information request received. A stacktrace will print followed by a 1.0 second profile
======================================================================================

signal (29): Information request: 29
__psynch_cvwait at /usr/lib/system/libsystem_kernel.dylib (unknown line)
_pthread_cond_wait at /usr/lib/system/libsystem_pthread.dylib (unknown line)
...

======================================================================
Profile collected. A report will print if the Profile module is loaded
======================================================================

Overhead ╎ [+additional indent] Count File:Line; Function
=========================================================
Thread 1 Task 0x000000011687c010 Total snapshots: 572. Utilization: 100%
   ╎147 @Base/client.jl:506; _start()
       ╎ 147 @Base/client.jl:318; exec_options(opts::Base.JLOptions)
...

Thread 2 Task 0x0000000116960010 Total snapshots: 572. Utilization: 0%
   ╎572 @Base/task.jl:587; task_done_hook(t::Task)
      ╎ 572 @Base/task.jl:879; wait()
...

Настройка

Длительность профилирования можно настроить с помощью Profile.set_peek_duration

Отчёт о профиле разбивается по потокам и задачам. Передайте функцию без аргументов в Profile.peek_report[] чтобы переопределить это. Например, Profile.peek_report[] = () -> Profile.print() для удаления группировки. Это также может быть переопределено внешним потребителем данных профиля.

Справочник

Profile.@profileМакрос

@profile

@profile <expression> выполняет ваше выражение, периодически делая дампы стека вызовов. Они добавляются к внутреннему буферу дампов стека.

Методы в Profile не экспортируются и должны вызываться, например, как Profile.print().

Profile.clearФункция

clear()

Очистить любые существующие дампы стека из внутреннего буфера.

Profile.printФункция

print([io::IO = stdout,] [data::Vector = fetch()], [lidict::Union{LineInfoDict, LineInfoFlatDict} = getdict(data)]; kwargs...)

Выводит результаты профилирования в io (по умолчанию, stdout). Если вы не предоставите вектор data, будет использован внутренний буфер накопленных дампов стека.

Ключевые аргументы могут быть любым сочетанием:

  • format – Определяет, выводятся ли дампы стека с (по умолчанию, :tree) или без (:flat) отступом, указывающим структуру дерева.

  • C – Если true, дампы стека из кода C и Fortran отображаются (обычно они исключаются).

  • combine – Если true (по умолчанию), указатели инструкций, соответствующие одной строке кода, объединяются.

  • maxdepth – Ограничивает глубину, превышающую maxdepth в формате :tree.

  • sortedby – Управляет порядком в формате :flat. :filefuncline (по умолчанию) сортирует по строке исходного кода, :count сортирует по количеству собранных выборок, а :overhead сортирует по количеству выборок, выпавших на каждую функцию.

  • groupby – Управляет группировкой по задачам и потокам или без группировки. Варианты: :none (по умолчанию), :thread, :task, [:thread, :task], или [:task, :thread], где последние два обеспечивают вложенную группировку.

  • noisefloor – Ограничивает кадры, которые превышают эвристическое пороговое значение шума выборки (применяется только к формату :tree). Рекомендуемое значение для попытки установить — 2.0 (по умолчанию 0). Этот параметр скрывает выборки, для которых n <= noisefloor * √N, где n — количество выборок в этой строке, а N — количество выборок для вызываемого объекта.

  • mincount – Ограничивает вывод только теми строками, у которых есть по крайней мере mincount вхождений.

  • recur – Управляет обработкой рекурсии в формате :tree. :off (по умолчанию) выводит дерево в обычном виде. :flat вместо этого сжимает любую рекурсию (по ip), показывая приблизительный эффект преобразования любой саморекурсии в итератор. :flatc делает то же самое, но также включает сжатие кадров C (может давать странные результаты вблизи jl_apply).

  • threads::Union{Int,AbstractVector{Int}} – Укажите, с каких потоков включать снимки в отчёте. Обратите внимание, что это не контролирует, на каких потоках собираются выборки (которые также могут быть собраны на другой машине).

  • tasks::Union{Int,AbstractVector{Int}} – Укажите, с каких задач включать снимки в отчёте. Обратите внимание, что это не контролирует, в каких задачах собираются выборки.

print([io::IO = stdout,] data::Vector, lidict::LineInfoDict; kwargs...)

Выводит результаты профилирования в io. Этот вариант используется для проверки результатов, экспортированных предыдущим вызовом retrieve. Передайте вектор data дампов стека и словарь lidict информации о строках.

См. Profile.print([io], data) для объяснения допустимых ключевых аргументов.

Profile.initФункция

init(; n::Integer, delay::Real)

Настройте интервал delay между дампами стека (в секундах) и количество n указателей инструкций, которые могут храниться на поток. Каждый указатель инструкции соответствует одной строке кода; дампы стека, как правило, содержат длинный список указателей инструкций. Обратите внимание, что 6 пространств для указателей инструкций на дамп стека используются для хранения метаданных и двух NULL-маркеров конца.

Текущие настройки можно получить, вызвав эту функцию без аргументов, и каждый параметр можно установить независимо, используя ключевые слова или в порядке (n, delay).

Начиная с Julia 1.8, эта функция выделяет место для n указателей инструкций на каждом профилируемом потоке. Ранее это было n в общей сложности.

Profile.fetchФункция

fetch(;include_meta = true) -> data

Возвращает копию буфера дампов стека профиля. Обратите внимание, что значения в data имеют смысл только на этой машине в текущем сеансе, потому что зависят от точных адресов памяти, используемых при JIT-компиляции. Эта функция предназначена в основном для внутреннего использования; retrieve может быть лучшим выбором для большинства пользователей. По умолчанию метаданные, такие как threadid и taskid, включены. Установите include_meta в false для удаления метаданных.

Profile.retrieveФункция

retrieve(; kwargs...) -> data, lidict

«Экспортирует» результаты профилирования в переносимом формате, возвращая набор всех дампов стека (data) и словарь, сопоставляющий (специфичные для сеанса) указатели инструкций в data с LineInfo значениями, которые хранят имя файла, имя функции и номер строки. Эта функция позволяет сохранять результаты профилирования для дальнейшего анализа.

Profile.callersФункция

callers(funcname, [data, lidict], [filename=<filename>], [linerange=<start:stop>]) -> Vector{Tuple{count, lineinfo}}

Учитывая предыдущую сессию профилирования, определите, кто вызвал определённую функцию. Предоставление имени файла (и, необязательно, диапазона номеров строк, в котором определяется функция) позволяет различать перегруженные методы. Возвращаемое значение — вектор, содержащий количество вызовов и информацию о строках вызывающего объекта. Необязательно можно предоставить дампы стека data , полученные из retrieve; в противном случае используется текущий внутренний буфер профиля.

Profile.clear_malloc_dataФункция

clear_malloc_data()

Очищает любые сохранённые данные о распределении памяти при выполнении julia с --track-allocation. Выполните команду(ы), которые вы хотите протестировать (чтобы принудительно выполнить JIT-компиляцию), а затем вызовите clear_malloc_data. Затем снова выполните свою команду(ы), выйдите из Julia и изучите полученные файлы *.mem.

Profile.get_peek_durationФункция

get_peek_duration()

Получить длительность в секундах «просмотра» профиля, который запускается через SIGINFO или SIGUSR1, в зависимости от платформы.

Profile.set_peek_durationФункция

set_peek_duration(t::Float64)

Установить длительность в секундах «просмотра» профиля, который запускается через SIGINFO или SIGUSR1, в зависимости от платформы.

Профилирование памяти

Profile.Allocs.@profileМакрос

Profile.Allocs.@profile [sample_rate=0.0001] expr

Профилировать распределения, которые происходят во время expr, возвращая как результат, так и структуру AllocResults.

Частота 1.0 будет записывать всё; 0.0 — ничего.

julia> Profile.Allocs.@profile sample_rate=0.01 peakflops()
1.03733270279065e11

julia> results = Profile.Allocs.fetch()

julia> last(sort(results.allocs, by=x->x.size))
Profile.Allocs.Alloc(Vector{Any}, Base.StackTraces.StackFrame[_new_array_ at array.c:127, ...], 5576)

Текущая реализация профайлера распределения не захватывает типы для всех распределений. Распределения, для которых профайлер не смог захватить тип, представлены как имеющие тип Profile.Allocs.UnknownType.

Вы можете узнать больше о недостающих типах и планах по улучшению этого по адресу: https://github.com/JuliaLang/julia/issues/43688.

Профайлер распределения был добавлен в Julia 1.8.

Методы в Profile.Allocs не экспортируются и должны вызываться, например, как Profile.Allocs.fetch().

Profile.Allocs.clearФункция

Profile.Allocs.clear()

Очистить ранее профилированную информацию о распределении из памяти.

Profile.Allocs.fetchФункция

Profile.Allocs.fetch()

Получить записанные распределения и декодировать их в объекты Julia, которые можно проанализировать.

Profile.Allocs.startФункция

Profile.Allocs.start(sample_rate::Real)

Начните запись распределения с заданной частотой дискретизации. Частота дискретизации 1,0 запишет все; 0,0 — ничего.

Profile.Allocs.stopФункция

Profile.Allocs.stop()

Остановить запись распределения.

© 2009–2022 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/v1.8/stdlib/Profile/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API