Spec-Zone.ru › Julia 1.9

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

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

Существует два основных подхода к профилированию кода 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 для автоматической записи снимка кучи heap snapshot.

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.

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)

Лучший способ визуализации в настоящее время – с помощью пакета 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)

Создать снимок кучи в формате JSON, ожидаемом просмотрщиком снимков кучи Chrome Devtools (.heapsnapshot), в файл ($pid_$timestamp.heapsnapshot) в текущем каталоге, или заданном пути к файлу, или потоке ввода-вывода. Если all_one равно true, то размер каждого объекта будет представлен единицей, что позволит их легко подсчитать. В противном случае будет указан фактический размер.

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

julia> using Profile

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

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

Полученный файл снимка кучи можно загрузить в Chrome Devtools для просмотра. Для получения дополнительной информации см. документацию Chrome Devtools.

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

Spec-Zone.ru

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