测试代码main.c#include pch.h #define PROFILING 1 #if PROFILING #define PROFILE_SCOPE(name) InstrumentationTimer timer##__LINE__(name); #ifdef _MSC_VER #define PROFILE_FUNCTION() PROFILE_SCOPE(__FUNCSIG__) #else #define PROFILE_FUNCTION() PROFILE_SCOPE(__PRETTY_FUNCTION__) #endif #else #define PROFILE_SCOPE(name) #define PROFILE_FUNCTION() #endif void Function(int value) { PROFILE_FUNCTION(); for (int i 0; i 1000 ; i) std::cout hello world # i std::endl; } void Function() { PROFILE_FUNCTION(); for (int i 0; i 1000 ; i) std::cout hello world # i std::endl; } void RunBenchmarks() { PROFILE_FUNCTION(); std::cout Running Benchmarks...\n; Function(2); Function(); } int main() { Instrumentor::Get().BeginSession(profile.json); // 开始追踪 RunBenchmarks(); Instrumentor::Get().EndSession(); // 结束追踪 std::cin.get(); }pch.h#pragma once #include iostream #include string #include vector #include memory #include fstream #include sstream #include thread #include mutex #include chrono #include functional #include algorithm #include csignal /* C 性能追踪器生成 Chrome Tracing 格式的 JSON 可在 Perfetto/ui.perfetto.dev 查看 */ class Instrumentor { private: std::ofstream m_OutputStream; bool m_FirstItem; Instrumentor() : m_FirstItem(true) {} public: static Instrumentor Get() { static Instrumentor instance; return instance; } void BeginSession(const std::string filepath results.json) { m_OutputStream.open(filepath); m_FirstItem true; WriteHeader(); } void EndSession() { WriteFooter(); m_OutputStream.close(); } void WriteProfile(const std::string name, long long start, long long end, std::thread::id threadID) { std::stringstream ss; if (!m_FirstItem) ss ,; m_FirstItem false; ss R({ cat: function, dur: ) (end - start) R(, name: ) name R(, ph: X, pid: 0, tid: ) threadID R(, ts: ) start R( }); m_OutputStream ss.str(); } private: void WriteHeader() { m_OutputStream R({traceEvents:[); } void WriteFooter() { m_OutputStream ]}; } }; // 计时器自动写入 JSON 文件 class InstrumentationTimer { private: const char* m_Name; std::chrono::time_pointstd::chrono::high_resolution_clock m_StartTimePoint; bool m_Stopped; public: InstrumentationTimer(const char* name) : m_Name(name), m_Stopped(false) { m_StartTimePoint std::chrono::high_resolution_clock::now(); } ~InstrumentationTimer() { if (!m_Stopped) Stop(); } void Stop() { auto endTimePoint std::chrono::high_resolution_clock::now(); long long start std::chrono::time_point_caststd::chrono::microseconds( m_StartTimePoint).time_since_epoch().count(); long long end std::chrono::time_point_caststd::chrono::microseconds( endTimePoint).time_since_epoch().count(); auto threadID std::this_thread::get_id(); Instrumentor::Get().WriteProfile(m_Name, start, end, threadID); m_Stopped true; } };Google Chrome 浏览器地址栏输入 https://ui.perfetto.dev/点击左侧的Open trace file 打开 生成的 profile.json 文件---------------------------------------------------------------------------------------------------------多线程测试代码#include pch.h #define PROFILING 1 #if PROFILING #define PROFILE_SCOPE(name) InstrumentationTimer timer##__LINE__(name) #ifdef _MSC_VER #define PROFILE_FUNCTION() PROFILE_SCOPE(__FUNCSIG__) #else #define PROFILE_FUNCTION() PROFILE_SCOPE(__PRETTY_FUNCTION__) #endif #else #define PROFILE_SCOPE(name) #define PROFILE_FUNCTION() #endif // 全局互斥锁保护 cout static std::mutex g_CoutMutex; void PrintWithLock(const std::string msg) { std::lock_guardstd::mutex lock(g_CoutMutex); std::cout msg; } void WorkerThread(int id) { PROFILE_FUNCTION(); for (int i 0; i 10; i) { { PROFILE_SCOPE(Worker Loop); PrintWithLock(Thread std::to_string(id) - iteration std::to_string(i) \n); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } } void HeavyWork(const char* name, int ms) { PROFILE_SCOPE(name); std::this_thread::sleep_for(std::chrono::milliseconds(ms)); } int main() { Instrumentor::Get().BeginSession(profile.json); { PROFILE_SCOPE(Main Thread Setup); PrintWithLock(Starting multithreaded benchmarks...\n); } // 启动 4 个线程 std::thread t1([]{ HeavyWork(Thread 1 Work A, 50); HeavyWork(Thread 1 Work B, 30); }); std::thread t2([]{ HeavyWork(Thread 2 Work, 80); }); std::thread t3([]{ HeavyWork(Thread 3 Work A, 40); HeavyWork(Thread 3 Work B, 20); }); std::thread t4([]{ HeavyWork(Thread 4 Work, 60); }); // 主线程也干活 HeavyWork(Main Thread Work, 45); t1.join(); t2.join(); t3.join(); t4.join(); Instrumentor::Get().EndSession(); PrintWithLock(\nDone! Load profile.json in https://ui.perfetto.dev/\n); std::cin.get(); }线程 t1 A(50ms) B(30ms) 80ms Thread 1 的 A 和 B 串行线程 t2 Work(80ms)线程 t3 A(40ms) B(20ms) 60ms Thread 3 的 A 和 B 串行线程 t4 Work(60ms)主线程 Work(45ms)所有线程同时跑总耗时 max(80, 80, 60, 60, 45) ≈ 80ms
C++ 可视化性能基准测试
测试代码main.c#include pch.h #define PROFILING 1 #if PROFILING #define PROFILE_SCOPE(name) InstrumentationTimer timer##__LINE__(name); #ifdef _MSC_VER #define PROFILE_FUNCTION() PROFILE_SCOPE(__FUNCSIG__) #else #define PROFILE_FUNCTION() PROFILE_SCOPE(__PRETTY_FUNCTION__) #endif #else #define PROFILE_SCOPE(name) #define PROFILE_FUNCTION() #endif void Function(int value) { PROFILE_FUNCTION(); for (int i 0; i 1000 ; i) std::cout hello world # i std::endl; } void Function() { PROFILE_FUNCTION(); for (int i 0; i 1000 ; i) std::cout hello world # i std::endl; } void RunBenchmarks() { PROFILE_FUNCTION(); std::cout Running Benchmarks...\n; Function(2); Function(); } int main() { Instrumentor::Get().BeginSession(profile.json); // 开始追踪 RunBenchmarks(); Instrumentor::Get().EndSession(); // 结束追踪 std::cin.get(); }pch.h#pragma once #include iostream #include string #include vector #include memory #include fstream #include sstream #include thread #include mutex #include chrono #include functional #include algorithm #include csignal /* C 性能追踪器生成 Chrome Tracing 格式的 JSON 可在 Perfetto/ui.perfetto.dev 查看 */ class Instrumentor { private: std::ofstream m_OutputStream; bool m_FirstItem; Instrumentor() : m_FirstItem(true) {} public: static Instrumentor Get() { static Instrumentor instance; return instance; } void BeginSession(const std::string filepath results.json) { m_OutputStream.open(filepath); m_FirstItem true; WriteHeader(); } void EndSession() { WriteFooter(); m_OutputStream.close(); } void WriteProfile(const std::string name, long long start, long long end, std::thread::id threadID) { std::stringstream ss; if (!m_FirstItem) ss ,; m_FirstItem false; ss R({ cat: function, dur: ) (end - start) R(, name: ) name R(, ph: X, pid: 0, tid: ) threadID R(, ts: ) start R( }); m_OutputStream ss.str(); } private: void WriteHeader() { m_OutputStream R({traceEvents:[); } void WriteFooter() { m_OutputStream ]}; } }; // 计时器自动写入 JSON 文件 class InstrumentationTimer { private: const char* m_Name; std::chrono::time_pointstd::chrono::high_resolution_clock m_StartTimePoint; bool m_Stopped; public: InstrumentationTimer(const char* name) : m_Name(name), m_Stopped(false) { m_StartTimePoint std::chrono::high_resolution_clock::now(); } ~InstrumentationTimer() { if (!m_Stopped) Stop(); } void Stop() { auto endTimePoint std::chrono::high_resolution_clock::now(); long long start std::chrono::time_point_caststd::chrono::microseconds( m_StartTimePoint).time_since_epoch().count(); long long end std::chrono::time_point_caststd::chrono::microseconds( endTimePoint).time_since_epoch().count(); auto threadID std::this_thread::get_id(); Instrumentor::Get().WriteProfile(m_Name, start, end, threadID); m_Stopped true; } };Google Chrome 浏览器地址栏输入 https://ui.perfetto.dev/点击左侧的Open trace file 打开 生成的 profile.json 文件---------------------------------------------------------------------------------------------------------多线程测试代码#include pch.h #define PROFILING 1 #if PROFILING #define PROFILE_SCOPE(name) InstrumentationTimer timer##__LINE__(name) #ifdef _MSC_VER #define PROFILE_FUNCTION() PROFILE_SCOPE(__FUNCSIG__) #else #define PROFILE_FUNCTION() PROFILE_SCOPE(__PRETTY_FUNCTION__) #endif #else #define PROFILE_SCOPE(name) #define PROFILE_FUNCTION() #endif // 全局互斥锁保护 cout static std::mutex g_CoutMutex; void PrintWithLock(const std::string msg) { std::lock_guardstd::mutex lock(g_CoutMutex); std::cout msg; } void WorkerThread(int id) { PROFILE_FUNCTION(); for (int i 0; i 10; i) { { PROFILE_SCOPE(Worker Loop); PrintWithLock(Thread std::to_string(id) - iteration std::to_string(i) \n); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } } void HeavyWork(const char* name, int ms) { PROFILE_SCOPE(name); std::this_thread::sleep_for(std::chrono::milliseconds(ms)); } int main() { Instrumentor::Get().BeginSession(profile.json); { PROFILE_SCOPE(Main Thread Setup); PrintWithLock(Starting multithreaded benchmarks...\n); } // 启动 4 个线程 std::thread t1([]{ HeavyWork(Thread 1 Work A, 50); HeavyWork(Thread 1 Work B, 30); }); std::thread t2([]{ HeavyWork(Thread 2 Work, 80); }); std::thread t3([]{ HeavyWork(Thread 3 Work A, 40); HeavyWork(Thread 3 Work B, 20); }); std::thread t4([]{ HeavyWork(Thread 4 Work, 60); }); // 主线程也干活 HeavyWork(Main Thread Work, 45); t1.join(); t2.join(); t3.join(); t4.join(); Instrumentor::Get().EndSession(); PrintWithLock(\nDone! Load profile.json in https://ui.perfetto.dev/\n); std::cin.get(); }线程 t1 A(50ms) B(30ms) 80ms Thread 1 的 A 和 B 串行线程 t2 Work(80ms)线程 t3 A(40ms) B(20ms) 60ms Thread 3 的 A 和 B 串行线程 t4 Work(60ms)主线程 Work(45ms)所有线程同时跑总耗时 max(80, 80, 60, 60, 45) ≈ 80ms