Google benchmark使用手册及范例
構(gòu)建集成
在robotic_arm的third_party已經(jīng)集成了benchmark,只需在相關(guān)測(cè)試用例代碼的CmakeLists.txt添加如下內(nèi)容:
target_link_libraries(xxx PRIVATE benchmark pthread)Demo樣例
存在以下模式樣例:
1. 使用BENCHMARK、BENCHMARK_MAIN宏
#include <benchmark/benchmark.h> #include <chrono> #include <thread>void BM_DemoSleep(benchmark::State& state) {for (auto _ : state){//待測(cè)試的代碼} } BENCHMARK(BM_DemoSleep); // 注冊(cè)要測(cè)試的函數(shù)對(duì)象BENCHMARK_MAIN(); // main函數(shù),運(yùn)行benchmark初始化和執(zhí)行2. 直接使用Benchmark相應(yīng)的接口
#include <benchmark/benchmark.h> #include <chrono> #include <thread>void BM_DemoSleep(benchmark::State& state) {for (auto _ : state){std::this_thread::sleep_for(std::chrono::nanoseconds(1000)); //待測(cè)試的代碼} }void BM_DemoSleep1(benchmark::State& state, int id) {std::cout << "id:"<< id << std::endl;for (auto _ : state){std::this_thread::sleep_for(std::chrono::nanoseconds(1000));} }int main(int argc, char** argv) {::benchmark::Initialize(&argc, argv); // 初始化Benchmarkif (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;// 使用函數(shù)指針注冊(cè)::benchmark::RegisterBenchmark("BM_DemoSleep", &BM_DemoSleep);// 使用Lamba函數(shù)注冊(cè)::benchmark::RegisterBenchmark("BM_DemoSleep1", [](benchmark::State& state){for (auto _ : state){std::this_thread::sleep_for(std::chrono::nanoseconds(1000));}});// 使用帶參數(shù)的函數(shù)指針注冊(cè)int id = 10;::benchmark::RegisterBenchmark("BM_DemoSleep2", &BM_DemoSleep1, id);::benchmark::RunSpecifiedBenchmarks(); // 運(yùn)行::benchmark::Shutdown(); }3. 使用Fixture
class BMDemo : public benchmark::Fixture { public:void SetUp(const benchmark::State& state) {id_ = 2;}void TearDown(const ::benchmark::State& state) {id_ = 0;}int GetId() const {return id_;}; private:int id_{0}; };BENCHMARK_F(BMDemo, Test0)(benchmark::State& state) {for (auto _ : state) {std::this_thread::sleep_for(std::chrono::milliseconds(GetId())); // test code} } BENCHMARK_F(BMDemo, Test1)(benchmark::State& state) {for (auto _ : state) {std::this_thread::sleep_for(std::chrono::milliseconds(GetId())); // test code} }原理:BENCHMARK_F(BMDemo, Test0)(benchmark::State& state){},會(huì)創(chuàng)建一個(gè)BMDemo_Test0_Benchmark的類(lèi),繼承至BMDemo,然后實(shí)現(xiàn)BMDemo_Test0_Benchmark::BenchmarkCase(benchmark::State& state){}成員函數(shù);在Fixture的Run方法中會(huì)一次調(diào)用SetUp->BenchmarkCase->TearDown
配置參數(shù)
1. Arg參數(shù)
| Benchmark* Arg(int64_t x); | 向Benchmark對(duì)象的std::vector<std::vector<int64_t> > args_添加一個(gè)元素(元素為vector{x}) |
| Benchmark* Range(int64_t start, int64_t limit); | Benchmark* Range(int64_t start, int64_t limit); |
| Benchmark* DenseRange(int64_t start, int64_t limit, int step = 1); | Benchmark* DenseRange(int64_t start, int64_t limit, int step = 1); |
| Benchmark* Args(const std::vector<int64_t>& args); | 向Benchmark對(duì)象的std::vector<std::vector<int64_t> > args_添加一個(gè)元素(元素為args) |
| Benchmark* ArgPair(int64_t x, int64_t y) | 向Benchmark對(duì)象的std::vector<std::vector<int64_t> > args_添加一個(gè)元素(元素為vector{x,y}) |
2. 測(cè)試多少次(iterations)
會(huì)有如下策略(簡(jiǎn)單的將如果沒(méi)有明確設(shè)置iteration,會(huì)使用相應(yīng)的計(jì)算方法(會(huì)使用到min_time),遞增迭代次數(shù)然后以最后一個(gè)確定的結(jié)果report):
我們可能逐漸增加基準(zhǔn)的長(zhǎng)度(迭代次數(shù)),直到我們確定結(jié)果是重要的。 一旦我們這樣做了,我們就會(huì)報(bào)告最后的結(jié)果并退出。 請(qǐng)注意,如果有重復(fù),則迭代計(jì)數(shù)僅為第一次重復(fù)計(jì)算,其他重復(fù)僅使用該預(yù)先計(jì)算的迭代計(jì)數(shù)。
3. 重復(fù)多少次(Repetitions)
指的是整個(gè)函數(shù)對(duì)象調(diào)用多少次,默認(rèn)值是1
::benchmark::RegisterBenchmark("BM_Arg", &BM_Arg)->Iterations(10)->Repetitions(3); // 迭代執(zhí)行10次,也就是for(auto _ : state){}循環(huán)會(huì)迭代10次; 重復(fù)調(diào)用3次4. 顯示時(shí)間單位
Benchmark* Unit(TimeUnit unit);
設(shè)置顯示時(shí)間單位:
kNanosecond, kMicrosecond, kMillisecond, kSecond.
5. 多線程
| Benchmark* Threads(int t); | 設(shè)置多少個(gè)線程運(yùn)行測(cè)試(線程函數(shù)中運(yùn)行注冊(cè)的函數(shù)對(duì)象) |
| Benchmark* ThreadRange(int min_threads, int max_threads); | 類(lèi)似args_, 以min_threads為起點(diǎn),倍率為2,終點(diǎn)為 max_threads,向thread_counts_添加元素比如: Range(1, 16), Threads(1)->Threads(2)-> Threads(4)-> Threads(8)-> Threads(16),分別以1、2、4、8、16個(gè)線程進(jìn)行測(cè)試 |
| Benchmark* DenseThreadRange(int min_threads, int max_threads, int stride = 1); | 類(lèi)似args_, 以min_threads為起點(diǎn),步長(zhǎng)為1,終點(diǎn)為 max_threads,向thread_counts_添加元素,DenseThreadRange(1, 8, 3), 1、4、7、8個(gè)線程進(jìn)行測(cè)試 |
6. 時(shí)間類(lèi)型
void BM_Arg(benchmark::State& state) {for (auto _ : state) {auto start = std::chrono::high_resolution_clock::now();// Simulate some useful workload with a sleepstd::this_thread::sleep_for(sleep_duration);auto end = std::chrono::high_resolution_clock::now();auto elapsed_seconds =std::chrono::duration_cast<std::chrono::duration<double>>(end - start);state.SetIterationTime(elapsed_seconds.count());}}::benchmark::RegisterBenchmark("BM_Arg", &BM_Arg)->UseManualTime();7. 統(tǒng)計(jì)分析結(jié)果
會(huì)統(tǒng)計(jì)每次的結(jié)果,然后輸出分析結(jié)果:
mean: 平均值、median: 中值、stddev: 標(biāo)準(zhǔn)差、cv:標(biāo)準(zhǔn)差/平均值
自定義分析結(jié)果,比如最小值,最大值
接口:
示例:
::benchmark::RegisterBenchmark("BM_Arg", &BM_Arg)->Iterations(10)->Repetitions(10)->Unit(benchmark::kMillisecond)->ComputeStatistics("max", [](const std::vector<double>& v)->double{return *std::max_element(v.begin(), v.end());}, benchmark::kTime)->ComputeStatistics("min", [](const std::vector<double>& v)->double{return *std::min_element(v.begin(), v.end());}, benchmark::kTime);命令行
–benchmark_out_format=<console|json|csv>
定義輸出格式
–benchmark_out=
定義文件名
–benchmark_filter=
定義過(guò)濾規(guī)則(正則表達(dá)式)
–benchmark_repetitions=n
定義重復(fù)次數(shù)
–benchmark_report_aggregates_only={true|false}
上報(bào)內(nèi)容是否只上報(bào)聚合內(nèi)容(省略每次repetition的內(nèi)容)
–benchmark_display_aggregates_only={true|false}
屏幕輸出內(nèi)容是否只上報(bào)聚合內(nèi)容(省略每次repetition的內(nèi)容)
其他
模版方法和模版Fixture本文無(wú)介紹,相關(guān)使用方法可以參考google benchmark的github地址
總結(jié)
以上是生活随笔為你收集整理的Google benchmark使用手册及范例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: BL5372 RTC linux驱动
- 下一篇: Benchmark和Baseline的含