17个稳定版本

1.8.0 2024年5月5日
1.7.1 2024年2月24日
1.6.1 2023年11月20日
1.5.0 2023年7月31日
1.1.1 2022年5月26日

#89 in 内存管理

Download history 93/week @ 2024-04-29 44/week @ 2024-05-06 67/week @ 2024-05-20 24/week @ 2024-05-27 20/week @ 2024-06-03 7/week @ 2024-06-10 10/week @ 2024-06-17 57/week @ 2024-06-24 6/week @ 2024-07-01 9/week @ 2024-07-08 21/week @ 2024-07-15 2/week @ 2024-07-22 13/week @ 2024-07-29 26/week @ 2024-08-05 8/week @ 2024-08-12

53 每月下载量

MIT 许可证

60KB
1.5K SLoC

Tracy分析器的完整Rust绑定。

入门指南

只需将以下内容添加到您的 Cargo.toml

[dependencies.tracy]
package = "tracy_full"
version = "1.3.0"

要启用构建的分析,请添加 enable 功能

[dependencies.tracy]
...
features = ["enable"]

功能

分配跟踪

#[global_allocator]
static ALLOC: tracy::GlobalAllocator = tracy::GlobalAllocator::new();

此功能跟踪所有分配,使用默认的 System 分配器进行分配。

对于自定义分配器

#[global_allocator]
static ALLOC: tracy::GlobalAllocator<MyAlloc> = tracy::GlobalAllocator::new_with(MyAlloc::new());

Tracy还支持使用 allocator_api 功能跟踪自定义分配器

[dependencies.tracy]
...
features = ["allocator_api"]
let alloc = TrackedAllocator::new(alloc, tracy::c_str!("TrackedAllocator"));

这将在Tracy中创建一个名为 TrackedAllocator 的内存池。

所有分配器都有一个 *Sampled 变体,它在每次分配时采样调用栈。

帧标记

使用以下方法标记主帧的结束

use tracy::frame;

frame!();

使用以下方法标记子帧的结束

frame!("Name");

使用以下方法标记不连续帧的作用域

frame!(discontinuous "Name");

帧类型之间的区别

主帧通常被认为是“帧”。它通常放置在主线程上的swapchain present调用之后。

子帧是主帧的一部分,例如,输入收集、物理和渲染

loop {
    // Gather input
    frame!("Input");
    // Process input
    frame!("Processing");
    // Render
    frame!("Render");

    swapchain.present();
    frame!();
}

不连续帧是与主线程上的帧不同步的帧。这可能包括不同线程上的异步资源加载等。

绘图

您可以在Tracy中绘制图形

use tracy::plotter;

let plotter = plotter!("MyGraph");
plotter.value(1.0);
plotter.value(2.0);

区域

use tracy::zone;

zone!(); // Zone with no name
zone!("MyZone"); // Zone with name "MyZone"
zone!(tracy::color::RED); // Zone with color red
zone!("MyZone", true); // Zone with name "MyZone", and enabled with a runtime expression.
zone!(tracy::color::RED, true); // Zone with color red, and enabled with a runtime expression.
zone!("MyZone", tracy::color::RED, true); // Zone with name "MyZone", color red, and enabled with a runtime expression.

所有区域从创建到封装作用域的结束都会进行分析。

额外功能

未来支持

Tracy可以将未来表示为纤维。必须启用 futures 功能。

[dependencies.tracy]
...
features = ["enable", "futures"]
use tracy::future;

trace_future!(async_function(), "Async Function").await;

不稳定

unstable 功能允许进行需要夜间编译器的优化。

[dependencies.tracy]
...
features = ["enable", "unstable"]

外部库集成

bevy

启用 bevy 功能以能够分析Bevy系统。

[dependencies.tracy]
...
features = ["enable", "bevy"]
use tracy::bevy::timeline;

App::new().add_system(timeline(my_system)).run();

这将在tracy时间线中为系统创建一个单独的纤维。

tracing

启用 tracing 功能以能够分析跟踪跨度。

[dependencies.tracy]
...
features = ["enable", "tracing"]
use tracy::tracing::TracyLayer;

tracing::subscriber::set_global_default(
    tracing_subscriber::registry().with(TracyLayer)
);

wgpu

启用 wgpu 功能以能够分析wgpu命令编码器和渲染/计算通道。

[dependencies.tracy]
...
features = ["enable", "wgpu"]
use tracy::wgpu::ProfileContext;

let mut profile_context = ProfileContext::with_name("Name", &adapter, &device, &queue, buffered_frames);

buffered_frames:您希望分析器缓冲的帧数。注意,您必须相应地同步主机和设备,否则调用 end_frame 将会引发恐慌。

您还需要为每个主机线程有一个 ProfileContext

您可以创建一个分析命令编码器

use tracy::{wgpu_command_encoder, wgpu_render_pass, wgpu_compute_pass};

let mut command_encoder = wgpu_command_encoder!(device, profile_context, desc);
{
    let render_pass = wgpu_render_pass!(command_encoder, desc)
}

{
    let compute_pass = wgpu_compute_pass!(command_encoder, desc)
}

在每个帧的末尾,您必须调用 end_frame

profile_context.end_frame(&device, &queue);

这会将分析数据上传到 Tracy。

依赖项

~1–34MB
~516K SLoC