Minitrace使用方法
trace是chrome中的开源运行性能测试工具,使用它我们可以直观地查看各线程的运行情况。根据各线程程序运行时间确定瓶颈,便于我们进行针对性的优化。
https://github.com/google/tracing-framework
但是整个工程比较庞大,使用部署并不方便。幸运的是在github上开源了另一个项目minitrace。https://github.com/hrydgard/minitrace
使用minitrace只需要使用工程下的两个minitrace.h和minitrace.c就可以了。将两个文件放在自己的C++工程目录下,include成功之后就可以调用MTR的接口,进行时间打点。MTR_BEGIN记录开始时间;MTR_END记录结束时间。运行后生成一个json文件;这时打开谷歌浏览器地址栏输入chrome://tracing,进入trace的界面,最后load你的json文件,就可以从界面中看到各线程的运行时间了。
下面是一个简单的3个线程的例子,数值A自增5次,b线程将数值A提取到数值B,c线程将B提取到C,用数值代替容器容量模拟简单的生产者消费者模式。
#include "minitrace.h"
#include<iostream>
#include<thread>
#include <mutex>
std::mutex _mutex;
std::condition_variable cvA,cvB;
int A = 0;
int B = 0;
int C = 0;
bool Exit = false;
void c() {
MTR_META_PROCESS_NAME("C");
MTR_META_THREAD_NAME("C thread");
while (1) {
std::unique_lock<std::mutex> lk(_mutex);
cvB.wait(lk, [&]() { return B > 0 || Exit; });
if (Exit) { break; }
MTR_BEGIN("", "B--;C++");
std::this_thread::sleep_for(std::chrono::milliseconds(30));
B--; C++;
std::cout << "b->c" << std::endl;
MTR_END("", "B--;C++");
}
}
void b() {
MTR_META_PROCESS_NAME("B");
MTR_META_THREAD_NAME("B thread");
while (1) {
std::unique_lock<std::mutex> lk(_mutex);
cvA.wait(lk, [&]() { return A > 0 || Exit; });
if (Exit) { cvB.notify_one(); break; }
MTR_BEGIN("", "A--;B++");
std::this_thread::sleep_for(std::chrono::milliseconds(20));
A--; B++;
std::cout << "a->b" << std::endl;
MTR_END("", "A--;B++");
cvB.notify_one();
}
}
void a() {
MTR_META_PROCESS_NAME("A");
MTR_META_THREAD_NAME("A thread");
for(int i = 0;i<5;i++){
std::unique_lock<std::mutex> lk(_mutex);
MTR_BEGIN("", "A++");
std::this_thread::sleep_for(std::chrono::milliseconds(10));
A++;
std::cout << "a++" << std::endl;
MTR_END("", "A++");
cvA.notify_one();
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
Exit = true;
std::cout << "Exit!";
cvA.notify_one();
}
int main() {
mtr_init("trace.json");
mtr_register_sigint_handler();
MTR_META_PROCESS_NAME("main");
MTR_META_THREAD_NAME("main thread");
std::thread ta(a);
std::thread tb(b);
std::thread tc(c);
ta.join();
tb.join();
tc.join();
mtr_flush();
mtr_shutdown();
return 0;
}
运行结果不唯一
a++
a++
a->b
a->b
b->c
b->c
a++
a++
a++
a->b
a->b
b->c
a->b
b->c
b->c
Exit!
最后找到我们的json文件,拖入到chrome://tracing页面中,就可以看到三个线程的实际运行情况了。