构建集成

在robotic_arm的third_party已经集成了benchmark,只需在相关测试用例代码的CmakeLists.txt添加如下内容:

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){//待测试的代码}
}
BENCHMARK(BM_DemoSleep); // 注册要测试的函数对象BENCHMARK_MAIN(); // main函数,运行benchmark初始化和执行

2. 直接使用Benchmark相应的接口

#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)); //待测试的代码}
}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;// 使用函数指针注册::benchmark::RegisterBenchmark("BM_DemoSleep", &BM_DemoSleep);// 使用Lamba函数注册::benchmark::RegisterBenchmark("BM_DemoSleep1", [](benchmark::State& state){for (auto _ : state){std::this_thread::sleep_for(std::chrono::nanoseconds(1000));}});// 使用带参数的函数指针注册int id = 10;::benchmark::RegisterBenchmark("BM_DemoSleep2", &BM_DemoSleep1, id);::benchmark::RunSpecifiedBenchmarks(); // 运行::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){},会创建一个BMDemo_Test0_Benchmark的类,继承至BMDemo,然后实现BMDemo_Test0_Benchmark::BenchmarkCase(benchmark::State& state){}成员函数;在Fixture的Run方法中会一次调用SetUp->BenchmarkCase->TearDown

配置参数

1. Arg参数

接口名称 作用
Benchmark* Arg(int64_t x); 向Benchmark对象的std::vector<std::vector<int64_t> > args_添加一个元素(元素为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对象的std::vector<std::vector<int64_t> > args_添加一个元素(元素为args)
Benchmark* ArgPair(int64_t x, int64_t y) 向Benchmark对象的std::vector<std::vector<int64_t> > args_添加一个元素(元素为vector{x,y})
void BM_Arg(benchmark::State& state) {std::cout << "arg1:" << state.range(0) << "\n"; // state.range(0)获取参数for (auto _ : state) {std::this_thread::sleep_for(std::chrono::milliseconds(state.range(0)));}
}int main(int argc, char** argv) {::benchmark::Initialize(&argc, argv);if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;::benchmark::RegisterBenchmark("BM_Arg", &BM_Arg)->Arg(10); // ->Arg()设置单个参数::benchmark::RegisterBenchmark("BM_Arg", &BM_Arg)->Arg(10)->Arg(11); //分别以10,11参数运行BM_Arg::benchmark::RunSpecifiedBenchmarks();::benchmark::Shutdown();
}

2. 测试多少次(iterations)

会有如下策略(简单的将如果没有明确设置iteration,会使用相应的计算方法(会使用到min_time),递增迭代次数然后以最后一个确定的结果report):
我们可能逐渐增加基准的长度(迭代次数),直到我们确定结果是重要的。 一旦我们这样做了,我们就会报告最后的结果并退出。 请注意,如果有重复,则迭代计数仅为第一次重复计算,其他重复仅使用该预先计算的迭代计数。

::benchmark::RegisterBenchmark("BM_Arg", &BM_Arg)->Iterations(10); // 迭代执行10次,也就是for(auto _ : state){}循环会迭代10次::benchmark::RegisterBenchmark("BM_Arg", &BM_Arg); // 会按照计算规则,迭代n次

3. 重复多少次(Repetitions)

指的是整个函数对象调用多少次,默认值是1

::benchmark::RegisterBenchmark("BM_Arg", &BM_Arg)->Iterations(10)->Repetitions(3); // 迭代执行10次,也就是for(auto _ : state){}循环会迭代10次; 重复调用3次

4. 显示时间单位

Benchmark* Unit(TimeUnit unit);
设置显示时间单位:
kNanosecond, kMicrosecond, kMillisecond, kSecond.

5. 多线程

Benchmark* Threads(int t); 设置多少个线程运行测试(线程函数中运行注册的函数对象)
Benchmark* ThreadRange(int min_threads, int max_threads); 类似args_, 以min_threads为起点,倍率为2,终点为 max_threads,向thread_counts_添加元素比如: Range(1, 16), Threads(1)->Threads(2)-> Threads(4)-> Threads(8)-> Threads(16),分别以1、2、4、8、16个线程进行测试
Benchmark* DenseThreadRange(int min_threads, int max_threads, int stride = 1); 类似args_, 以min_threads为起点,步长为1,终点为 max_threads,向thread_counts_添加元素,DenseThreadRange(1, 8, 3), 1、4、7、8个线程进行测试

6. 时间类型

  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. 统计分析结果

会统计每次的结果,然后输出分析结果:
mean: 平均值、median: 中值、stddev: 标准差、cv:标准差/平均值
自定义分析结果,比如最小值,最大值
接口:

  typedef double(StatisticsFunc)(const std::vector<double>&);Benchmark* ComputeStatistics(std::string name, StatisticsFunc* statistics,StatisticUnit unit = kTime);

示例:

::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=
定义过滤规则(正则表达式)
–benchmark_repetitions=n
定义重复次数
–benchmark_report_aggregates_only={true|false}
上报内容是否只上报聚合内容(省略每次repetition的内容)
–benchmark_display_aggregates_only={true|false}
屏幕输出内容是否只上报聚合内容(省略每次repetition的内容)

其他

模版方法和模版Fixture本文无介绍,相关使用方法可以参考google benchmark的github地址

Google benchmark使用手册及范例相关推荐

  1. Google Benchmark Google Test

    一个学习链接 GITHUB上的google-benchmark链接 google-benchmark的快速链接 cmake升级 安装步骤及简单测试过程 GTEST-写的很不错 GITHUB中的goog ...

  2. Google 面试学习手册,来看看谷歌,微软等大厂都面试什么

    今天我在浏览 GitHub 的时候,看到一个热门库,是外国的一位叫:jwasham ,整理的大厂面试手册和题目.他在根据整理的这个学习清单计划后,成为了亚马逊的开发工程师,所以他整理的这些题目和资料非 ...

  3. Google hack语法

    基础语法: 1.语法说明: inurl: 在url地址栏中显示的信息页面 intext: 显示在正文信息中的内容页面 site: 限制显示你某个域名的所有页面 filetype: 搜索文件的后缀或者扩 ...

  4. Google Filament 源码学习(二):三方库分类总结

    前言 拿到Filament代码一头雾水,到底要怎么看呢,先从第三方库看起吧,如下对三方库进行了分类梳理. 注:刚刚开始学习,有很多库和基本概念都不是很清楚,有不当之处请大家随时指出,本人一定虚心接受. ...

  5. Google 华章企业书架

    Google & 华章企业书架 2009年5月书架更新图书: 一.Google相关图书 26262  <Google Hacking技术手册>  25598  <登上Goog ...

  6. Google离线地图API概要解析

    Google离线地图API概要解析 发布时间:2018-01-17 版权: 1.说明 离线地图发布有多种方式均可以实现,可以利用ArcGis Server.GeoServer等构建地图Web服务器,还 ...

  7. google地图学习笔记(1)

    google地图学习笔记(1) 文章目录 google地图学习笔记(1) 关于API_KEY的说明 第一个程序:Hello World 支持的地图类型 zoom高度 API Key google地图A ...

  8. 〔转载〕Google,这个时代伪知识分子的载体

    Google,这个时代伪知识分子的载体 作者:朱步冲 尚进 | 2005-01-13 | 原始出处: 三联生活周刊 [内容提要]在Google位于加利福尼亚山景路的总部,接待台后面堆放着将近200台破 ...

  9. Google惩罚日本网站:PR由9下降到5

    此前,有消息称,Google日本分公司向一些博客付费,鼓励这些博客撰写文章宣传Google.Goolge总部日前紧急叫停了日本公司的这一做法并向用户致歉.Google同时将日本网站的PageRank值 ...

最新文章

  1. RIFF格式声音文件的实现(转)
  2. NBT:MaPS-seq测序方法揭示肠道微生物空间分布
  3. 华为自动驾驶实车实路测试视频曝光!
  4. linux运维工程师
  5. 微软全都要!Win10引入真Linux内核
  6. 计算机学科技术前沿:互联网上信息可信性的现状
  7. 从request中获取上一个请求的url
  8. 超大背包问题(折半枚举, 双向搜索)
  9. elasticsearch 请求全部数据
  10. 【路径规划】基于matlab无线充电车辆路径和速度预测【含Matlab源码 1473期】
  11. Unity 自学与进阶必会目录
  12. 基于单片机的温度监测系统设计(#0411)
  13. 三个数比较大小函数调用c语言,C语言程序系列第四弹–max函数判断三个数的大小...
  14. CTU CU CB PU TU
  15. 百度这个写在控制台的消息:2021百度校招
  16. OpenCV视频篇——颜色跟踪
  17. sql/oracle数据库之取整函数round()、ceil()、floor()等等及示例
  18. 云计算迁移流程,主要分为哪几步?
  19. VBA通达信股票交易接口获得方法
  20. 6大常用数据分析模型详解

热门文章

  1. 什么是项目ERP系统?
  2. 20220215-CTF-MISC-BUUCTF-ningen--binwalk分析---dd命令分离--ARCHPR暴力破解
  3. Linux云计算架构-docker容器命名和资源配额控制(2)
  4. 网络推广常见的几种方式
  5. JS如何取得URL里的参数?
  6. 解决word中无法粘贴问题(Ctrl+V失灵问题)
  7. NRZ 对比 PAM4 调制技术
  8. asp.net网站修改aspx.cs文件后如何不替换网站就生效
  9. 一个老牛的视频sdk
  10. 传《斗战神》美术创作婉拒暴雪挖角 中国游戏人缺少这份傲骨