AnyMath 文档

资料分析

CPU分析

CPU性能分析julia代码主要有两种方法:

@个人资料

通过 @个人资料 宏。

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 或通过一个 [医]锡金 信号到julia进程即 %kill-INFO$julia_pid *Linux:通过A SIGUSR1 信号到julia进程即 %杀-USR1$julia_pid *Windows:目前不支持。

首先,在信号被抛出的瞬间显示一个堆栈跟踪,然后收集一个1秒的概要文件,然后在下一个屈服点的概要文件报告,这可能是在没有屈服点的代码的任务完成,例如紧循环。

可选设置环境变量 JULIA_PROFILE_PEEK_HEAP_SNAPSHOT1 还要自动收集一个 堆快照

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()
...

定制化

分析的持续时间可通过以下方式进行调整 个人资料。set_peek_duration

配置文件报告按线程和任务细分。 传递一个no-arg函数给 个人资料。peek_report[] 来复盖这个。 即 个人资料。peek_report[]=()->配置文件。打印() 以移除任何分组。 这也可能被外部配置文件数据使用者复盖。

参考资料

@profile

@个人资料<表达式> 运行您的表达式,同时采取定期回溯。 这些附加到回溯的内部缓冲区。

中的方法 个人资料 不导出,需要调用,例如 个人资料。印刷().

clear()

清除内部缓冲区中的任何现有回溯。

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

将分析结果打印到 伊俄 (默认情况下, 标准输出). 如果你不提供 数据资料 矢量,将使用累积回溯的内部缓冲区。 路径是支持的终端中的可点击链接,专门用于 朱莉亚*编辑与行号,或只是文件链接,如果没有设置编辑器。

关键字参数可以是:

* 格式 --确定是否打印回溯(默认值, :树)或没有(:平)表示树结构的缩进。 * C --如果 真的,显示C和Fortran代码的回溯(通常它们被排除在外)。 * 联合收割机 --如果 真的 (默认),指令指针被合并,对应于同一行代码。 * 最大深度 --限制深度高于 最大深度:树 格式。 * 索特比 --控制订单 :平 格式。 :filefuncline (默认)按源行排序, :计数 按收集样本数目排序,以及 :开销 按每个函数自身产生的样本数排序。 * 组比 --控制对任务和线程进行分组,或不进行分组。 选项是 :无 (默认), :线程, :任务, [:线程,:任务],或 [:任务,:线程] 其中最后两个提供嵌套分组。 * 噪音地板 --限制超过样本启发式噪底的帧(仅适用于格式 :树). 为此尝试的建议值为2.0(默认值为0)。 此参数隐藏其样本 n<=noisefloor&ast;√N,在哪里 n 是这条线上的样本数量,并且 N 是被调用方的样本数。 * n.小额 --将打印输出限制为只有那些至少有 最小人数 发生。 * [医]复发 --控制递归处理 :树 格式。 :关闭 (默认)正常打印树。 :平 相反,压缩任何递归(通过ip),显示将任何自递归转换为迭代器的近似效果。 :flatc 做同样的事情,但也包括c帧的折叠(可能会做一些奇怪的事情 jl_应用). * 线程::联合{Int,AbstractVector{Int}} --指定要在报告中包含快照的线程。 请注意,这不会控制在哪些线程上收集样本(也可能在另一台机器上收集)。 * 任务::联合{Int,AbstractVector{Int}} --指定要在报告中包含快照的任务。 请注意,这不会控制在哪些任务中收集样本。

兼容性

朱莉娅1.8 组比, 线程,而 任务 在Julia1.8中引入了关键字参数。

注意Windows上的分析仅限于主线程。 其他线程尚未采样,也不会显示在报告中。

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

将分析结果打印到 伊俄. 此变体用于检查由以前的调用导出的结果 检索. 提供向量 数据资料 回溯和字典 [医]利迪特 行信息。

个人资料。打印([io],数据) 有关有效关键字参数的解释。

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

配置 延迟 回溯之间(以秒为单位),和数字 n 每个线程可能存储的指令指针。 每个指令指针对应于一行代码;回溯通常由一长串指令指针组成。 请注意,每个回溯的指令指针有6个空格用于存储元数据和两个空结束标记。 当前的设置可以通过调用此函数而不使用参数来获得,并且每个设置都可以使用关键字或按顺序独立设置 (n,延迟).

fetch(;include_meta = true) -> data

返回配置文件回溯的缓冲区的副本。 请注意,在值 数据资料 在当前会话中只对这台机器有意义,因为它取决于JIT编译中使用的确切内存地址。 此功能主要用于内部使用; 检索可能是大多数用户更好的选择。 默认情况下,包括threadid和taskid等元数据。 套装 包括_meta错误 以剥离元数据。

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

"导出"分析结果为可移植格式,返回所有回溯的集合(数据资料)和映射(会话特定)指令指针的字典 数据资料线信息 存储文件名、函数名和行号的值。 此功能允许您保存分析结果以供将来分析。

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

给定先前的分析运行,确定谁调用了特定函数。 提供文件名(以及可选的定义函数的行号范围)允许您消除重载方法的歧义。 返回的值是一个包含呼叫次数计数和有关呼叫者的线路信息的向量。 一个可以选择提供backtrace 数据资料检索;否则,使用当前内部配置文件缓冲区。

clear_malloc_data()

在运行julia时清除任何存储的内存分配数据 --轨道-分配. 执行要测试的命令(强制JIT编译),然后调用 clear_malloc_data. 然后再次执行你的命令,退出Julia,并检查结果 *.梅姆 文件。

get_peek_duration()

获取通过以下方式触发的配置文件"peek"的持续时间(以秒为单位) [医]锡金SIGUSR1,取决于平台。

set_peek_duration(t::Float64)

设置通过以下方式触发的配置文件"peek"的持续时间(以秒为单位) [医]锡金SIGUSR1,取决于平台。

内存分析

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

期间发生的配置文件分配 expr,返回结果和分配结果结构。

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文档中的分析教程。

兼容性

Julia1.11Julia的旧版本无法在所有情况下捕获类型。 在Julia的旧版本中,如果您看到类型的分配 个人资料。分配。未知类型,这意味着探查器不知道分配了什么类型的对象。 这主要发生在分配来自编译器生成的生成代码时。 见https://github.com/JuliaLang/julia/issues/43688[问题#43688]欲了解更多信息.

自Julia1.11以来,所有分配都应该报告一个类型。
兼容性

Julia1.8在Julia1.8中添加了分配分析器。

中的方法 个人资料。分配;分配 不导出,需要调用,例如 个人资料。分配。取().

Profile.Allocs.clear()

从内存中清除所有以前分析过的分配信息。

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

将分析结果打印到 伊俄 (默认情况下, 标准输出). 如果你不提供 数据资料 矢量,将使用累积回溯的内部缓冲区。

个人资料。印刷业 有关有效关键字参数的解释。

Profile.Allocs.fetch()

检索记录的分配,并将其解码为可以分析的Julia对象。

Profile.Allocs.start(sample_rate::Real)

以给定的采样率开始记录分配1.0的采样率将记录所有内容0.0将不记录任何内容。

Profile.Allocs.stop()

停止记录分配。

堆快照

Profile.take_heap_snapshot(filepath::String, all_one::Bool=false;
                           redact_data::Bool=true, streaming::Bool=false)
Profile.take_heap_snapshot(all_one::Bool=false; redact_data:Bool=true,
                           dir::String=nothing, streaming::Bool=false)

编写堆的快照,以Chrome Devtools堆快照查看器预期的JSON格式(。heapsnapshot扩展名)到一个文件($pid_timestamp时间戳。堆弹,堆弹)默认情况下在当前目录中(如果当前目录不可写,则为tempdir),或者在 署长 如果给定,或给定的完整文件路径,或IO流。

如果 全音,全音 是真的,然后将每个对象的大小报告为一个,以便它们可以很容易地计数。 否则,报告实际大小。

如果 redact_数据 为true(默认),则不发出任何对象的内容。

如果 流媒体 确实,我们将快照数据流式传输到四个文件中,使用filepath作为前缀,以避免将整个快照保存在内存中。 此选项应用于内存受限的任何设置。 然后可以通过调用Profile重新组装这些文件。堆积如山。assemble_snapshot(),可以离线完成。

注意:出于性能原因,我们强烈建议设置streaming=true。 从部件重建快照需要将整个快照保存在内存中,因此如果快照很大,则在处理时可能会耗尽内存。 流式处理允许您在工作负载运行完成后脱机重建快照。 如果您尝试使用streaming=false(默认值,用于向后兼容性)收集快照,并且您的进程被杀死,请注意,这将始终将部分保存在与您提供的filepath相同的目录中,因此您仍然可以 汇编_snapshot().

中的方法 个人资料 不导出,需要调用,例如 个人资料。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)

其中"快照"是作为生成文件前缀的文件路径。

生成快照文件后,可以使用以下命令脱机组装它们:

julia> using Profile

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

生成的堆快照文件可以上传到chrome devtools进行查看。 有关更多信息,请参阅https://developer.chrome.com/docs/devtools/memory-problems/heap-snapshots/#view_snapshots[chrome devtools文档]。 分析Chromium堆快照的另一种方法是使用VS Code扩展 ms-vscode。vscode-js-profile-火焰.

Firefox堆快照的格式不同,Firefox目前可能用于查看Julia生成的堆快照。