Tracy Profiler 是目前 C++ 多线程程序实时性能分析工具

Tracy Profiler 是目前 C++ 多线程程序(游戏引擎、SLAM、视觉系统)里 最强的实时性能分析工具之一

它可以精确分析:

  • 线程运行时间
  • 线程等待时间
  • mutex 锁竞争
  • CPU cache miss
  • frame pipeline

对于 统计线程等待其他线程数据时间 ,Tracy 的 Zone + Lock Profiling 非常适合。


一、基础示例:统计线程等待数据时间

1 引入 Tracy

下载:

复制代码
https://github.com/wolfpld/tracy

项目中包含:

cpp 复制代码
Tracy.hpp
TracyClient.cpp

编译时需要:

cpp 复制代码
#define TRACY_ENABLE

2 示例代码

cpp 复制代码
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>

#define TRACY_ENABLE
#include "Tracy.hpp"

std::mutex mtx;
std::condition_variable cv;
std::queue<int> dataQueue;

bool running = true;

void producer()
{
    while (running)
    {
        ZoneScoped;  // Tracy 统计该函数执行时间

        std::this_thread::sleep_for(std::chrono::milliseconds(30));

        {
            std::lock_guard<std::mutex> lock(mtx);
            dataQueue.push(rand());
        }

        cv.notify_one();
    }
}

void consumer()
{
    while (running)
    {
        ZoneScoped;

        std::unique_lock<std::mutex> lock(mtx);

        ZoneScopedN("Waiting Data");

        cv.wait(lock, [] { return !dataQueue.empty(); });

        int value = dataQueue.front();
        dataQueue.pop();

        lock.unlock();

        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}

int main()
{
    tracy::SetThreadName("Main Thread");

    std::thread t1(producer);
    std::thread t2(consumer);

    tracy::SetThreadName("Producer");
    tracy::SetThreadName("Consumer");

    std::this_thread::sleep_for(std::chrono::seconds(10));

    running = false;

    t1.join();
    t2.join();
}

二、Tracy 显示效果

运行后打开:

复制代码
Tracy.exe

可以看到 timeline:

复制代码
Producer Thread
██████ compute
     ██████ compute

Consumer Thread
██ wait data
████ compute
██ wait data

你会看到:

复制代码
Waiting Data

这段时间就是 线程等待数据时间


三、精确统计 Mutex 等待时间

Tracy 还可以直接统计 锁竞争

使用:

cpp 复制代码
#include "TracyLock.hpp"

代码改为:

cpp 复制代码
tracy::Lockable<std::mutex> mtx;

示例:

cpp 复制代码
tracy::Lockable<std::mutex> mtx;

void consumer()
{
    while (running)
    {
        ZoneScoped;

        std::unique_lock<tracy::Lockable<std::mutex>> lock(mtx);

        cv.wait(lock, [] { return !dataQueue.empty(); });

        int value = dataQueue.front();
        dataQueue.pop();
    }
}

Tracy 会显示:

复制代码
Lock contention

并告诉你:

复制代码
Thread A waited 2.1 ms
Thread B waited 5.4 ms

四、视觉 SLAM 示例(Tracking 等待 Frame)

视觉系统常见 pipeline:

复制代码
Camera Thread
     ↓
Tracking Thread
     ↓
Mapping Thread

Tracking 等待 Frame:

cpp 复制代码
void TrackingThread()
{
    while (running)
    {
        ZoneScoped;

        std::unique_lock<std::mutex> lock(frameMutex);

        ZoneScopedN("Wait Frame");

        frameCV.wait(lock, [] { return !frameQueue.empty(); });

        Frame f = frameQueue.front();
        frameQueue.pop();

        lock.unlock();

        ProcessFrame(f);
    }
}

Tracy timeline:

复制代码
Tracking Thread

████ ProcessFrame
██ Wait Frame
████ ProcessFrame
██ Wait Frame

可以直观看到:

复制代码
等待时间
计算时间

五、统计 Frame Pipeline

SLAM 中推荐这样标记:

cpp 复制代码
void ProcessFrame()
{
    ZoneScopedN("Tracking");

    ExtractORB();
    PoseEstimation();
    LocalBA();
}

Tracy timeline:

复制代码
Frame 1

Tracking
 ├─ ExtractORB
 ├─ PoseEstimation
 └─ LocalBA

可以直接看到:

复制代码
哪个模块最慢

六、Frame profiler(视觉系统强烈推荐)

Tracy 还有 frame profiler

使用:

cpp 复制代码
FrameMark;

例如:

cpp 复制代码
while (running)
{
    FrameMark;

    ProcessFrame();
}

Tracy会显示:

复制代码
FPS
Frame time
Frame jitter

非常适合 视觉前端优化


七、Tracy 的优势

相比传统计时:

复制代码
chrono
printf

Tracy优势:

功能 Tracy
线程时间线
mutex等待
CPU cache miss
实时可视化
纳秒精度

八、SLAM项目推荐 instrumentation

建议标记:

复制代码
Tracking
FeatureExtraction
PoseOptimization
LocalMapping
LoopClosing

示例:

cpp 复制代码
ZoneScopedN("FeatureExtraction");

九、实际项目性能优化示例

很多视觉系统优化流程:

复制代码
1 查看线程 timeline
2 找到等待时间
3 找到锁竞争
4 调整 pipeline

例如:

复制代码
Tracking wait frame 40ms
Mapping compute 200ms

说明:

复制代码
Mapping 成为瓶颈

相关推荐
吹什么轩2 小时前
c++复习:模拟实现list来更好的理解和应用list
开发语言·c++
小白学大数据2 小时前
Python 爬虫实战:抓取汽车之家二手车成交价格与里程数据
开发语言·爬虫·python·汽车
AmyLin_20012 小时前
PDF 色彩保真工程实践【5】核心实现(下):拼装 Image XObject、页面资源与内容流
c++·pdf·sdk·颜色空间·印刷·icc·cmyk
可编程芯片开发2 小时前
基于双PI控制器结构的六步逆变器供电无刷直流电机调速simulink仿真
算法
深盾科技_Virbox2 小时前
软件加密工具怎么选:试用验证、采购成本与授权范围
开发语言·安全·软件需求
Sagittarius_A*2 小时前
后量子密码|通识认知 02|量子威胁核心原理:Shor 算法如何击穿传统公钥密码
算法·信息安全·密码学·量子计算
A_cainiao_A2 小时前
C++20:std::stop_source让线程说停就听
开发语言·c++20
青山木2 小时前
Hot 100 --- 在排序数组中查找元素的第一个和最后一个位置
java·数据结构·算法·leetcode
其美杰布-富贵-李3 小时前
聚类算法详解:K-means、层次聚类与 DBSCAN
算法·机器学习·kmeans·聚类
乱七八糟的屋子3 小时前
MTL4 (Matrix Template Library) 超详细实战教程|C++高性能稠密/稀疏矩阵计算
c++·矩阵·稀疏矩阵·mtl4·matrixtemplate·c++线性代数·高性能数值计算