Spec-Zone.ru › Julia 1.11

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

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

Существует два основных подхода к профилированию кода 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()

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

Profile.set_peek_durationФункция

set_peek_duration(t::Float64)

Установить продолжительность в секундах «просмотра» профиля, вызываемого 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)

Дополнительную информацию можно найти в учебнике по профилированию в документации Julia.

В более старых версиях Julia не удавалось захватывать типы во всех случаях. В более старых версиях Julia, если вы видите выделение типа Profile.Allocs.UnknownType, это означает, что профайлер не знает, какой тип объекта был выделен. Это, главным образом, происходило, когда выделение поступало из сгенерированного кода, созданного компилятором. Дополнительную информацию см. в вопросе #43688.

Начиная с Julia 1.11, все выделения должны иметь указанный тип.

Профилировщик выделений был добавлен в Julia 1.8.

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

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

Profile.Allocs.clear()

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

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

Profile.Allocs.print([io::IO = stdout,] [data::AllocResults = fetch()]; kwargs...)

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

См. Profile.print для объяснения допустимых ключевых аргументов.

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(filepath::String, all_one::Bool=false, streaming=false)
Profile.take_heap_snapshot(all_one::Bool=false; dir::String, streaming=false)

Записать снимок кучи в формате JSON, ожидаемом просмотрщиком снимков кучи Chrome Devtools (.heapsnapshot расширение), в файл ($pid_$timestamp.heapsnapshot) в текущем каталоге по умолчанию (или в tempdir, если текущий каталог недоступен для записи), или в dir, или в указанный полный путь к файлу, или в поток ввода-вывода.

Если all_one истинно, то размер каждого объекта указывается как единица, чтобы их можно было легко подсчитать. В противном случае, указывается фактический размер.

Если all_one истинно, мы выведем данные снимка в четыре файла, используя filepath в качестве префикса, чтобы избежать необходимости удерживать весь снимок в памяти. Этот параметр следует использовать в любой ситуации, когда у вас ограничена память. Эти файлы затем можно собрать, вызвав Profile.HeapSnapshot.assemble_snapshot(), что можно сделать автономно.

ПРИМЕЧАНИЕ. Мы настоятельно рекомендуем установить streaming=true по соображениям производительности. Восстановление снимка из частей требует удержания всего снимка в памяти, поэтому, если снимок большой, у вас может не хватить памяти при его обработке. С потоковой передачей вы можете восстановить снимок автономно после завершения вашей рабочей нагрузки. Если вы попытаетесь собрать снимок со значением streaming=false (по умолчанию, для обратной совместимости), и ваш процесс будет завершен, обратите внимание, что это всегда сохранит части в том же каталоге, что и ваш предоставленный filepath, так что вы все еще можете восстановить снимок позже, используя assemble_snapshot().

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

julia> using Profile

julia> Profile.take_heap_snapshot("snapshot.heapsnapshot")

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

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

julia> using Profile

julia> Profile.take_heap_snapshot("snapshot"; streaming=true)

где «snapshot» — это путь к файлу в качестве префикса для создаваемых файлов.

После создания файлов снимка их можно собрать автономно с помощью следующей команды:

julia> using Profile

julia> Profile.HeapSnapshot.assemble_snapshot("snapshot", "snapshot.heapsnapshot")

Полученный файл снимка кучи можно загрузить в 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.11/stdlib/Profile/

Spec-Zone.ru

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