Профилирование
Профилирование процессора
Существуют два основных подхода к профилированию кода 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_PROFILE_PEEK_HEAP_SNAPSHOT в значение 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в формате:treesortedby– Управляет порядком в формате: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}}– Укажите, от каких задач включать моментальные снимки в отчете. Обратите внимание, что это не контролирует, внутри каких задач собираются образцы.
Ключевые аргументы groupby, threads, и tasks были добавлены в Julia 1.8.
Профилирование в Windows ограничено главным потоком. Образцы из других потоков не были собраны и не будут отображаться в отчете.
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)
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()
Получите продолжительность в секундах профилирования "peek", которое запускается через SIGINFO или SIGUSR1, в зависимости от платформы.
Profile.set_peek_durationФункция
set_peek_duration(t::Float64)
Установите продолжительность в секундах профилирования "peek", которое запускается через SIGINFO или SIGUSR1, в зависимости от платформы.
Профилирование памяти
Profile.Allocs.@profileМакрос
Profile.Allocs.@profile [sample_rate=0.1] 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)
Лучший способ визуализировать это — с помощью пакета PProf.jl, вызвав PProf.Allocs.pprof.
Текущая реализация профилировщика выделений не захватывает типы для всех выделений. Выделения, для которых профилировщик не смог захватить тип, представлены как имеющие тип 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()
Остановить запись выделений.
исходный кодСнимки кучи
Profile.take_heap_snapshotФункция
Profile.take_heap_snapshot(io::IOStream, all_one::Bool=false) Profile.take_heap_snapshot(filepath::String, all_one::Bool=false) Profile.take_heap_snapshot(all_one::Bool=false; dir::String)
Сохранить снимок кучи в формате JSON, ожидаемом просмотрщиком снимков кучи Chrome Devtools (.heapsnapshot), в файл ($pid_$timestamp.heapsnapshot) по умолчанию в текущем каталоге (или в tempdir, если текущий каталог недоступен для записи), или в dir, если задано, или в указанный полный путь к файлу, или в поток ввода/вывода.
Если all_one равно true, то размер каждого объекта будет представлен как единица для удобства подсчёта. В противном случае, будет показан фактический размер.
Методы в Profile не экспортированы и должны вызываться, например, как Profile.take_heap_snapshot().
julia> using Profile
julia> Profile.take_heap_snapshot("snapshot.heapsnapshot")
Отслеживает и записывает объекты Julia в куче. Записываются только объекты, известные сборщику мусора Julia. Память, выделенная внешними библиотеками, не управляемыми сборщиком мусора, не будут отображаться в снимке.
Полученный файл снимка кучи можно загрузить в Chrome Devtools для просмотра. Дополнительную информацию см. в документации Chrome Devtools. Альтернативой для анализа снимков кучи Chromium является расширение для VS Code ms-vscode.vscode-js-profile-flame.
Снимки кучи Firefox имеют другой формат, и в настоящее время Firefox может не использоваться для просмотра снимков кучи, сгенерированных Julia.
© 2009–2024 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/v1.10/stdlib/Profile/