Spec-Zone.ru › Julia 1.10

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

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

Существуют два основных подхода к профилированию кода 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 в формате :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}} – Укажите, от каких задач включать моментальные снимки в отчете. Обратите внимание, что это не контролирует, внутри каких задач собираются образцы.

Ключевые аргументы 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/

Spec-Zone.ru

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