CARLA
 
载入中...
搜索中...
未找到
Profiler.cpp
浏览该文件的文档.
1// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7// 检查是否已定义LIBCARLA_ENABLE_PROFILER宏,如果没有,则定义它
8// 这个宏用于控制是否启用Carla的性能分析器功能
9#ifndef LIBCARLA_ENABLE_PROFILER
10# define LIBCARLA_ENABLE_PROFILER
11#endif // LIBCARLA_ENABLE_PROFILER
12
13// 引入Carla日志库的头文件,用于记录日志信息
14#include "carla/Logging.h"
15
16// 引入Carla版本信息的头文件,可能包含版本号、构建日期等信息
17#include "carla/Version.h"
18
19// 引入Carla性能分析器的头文件,包含性能分析相关的类和函数定义
21
22// 引入C++标准库中的文件流处理头文件,用于读写文件
23#include <fstream>
24
25// 引入C++标准库中的格式化输入输出头文件,用于设置输出格式
26#include <iomanip>
27
28// 引入C++标准库中的标准输入输出流头文件,用于控制台输入输出
29#include <iostream>
30
31// 引入C++标准库中的互斥锁头文件,用于实现线程同步
32#include <mutex>
33
34// 定义在carla::profiler::detail命名空间下的代码
35namespace carla {
36namespace profiler {
37namespace detail {
38
39// 定义一个模板辅助函数,用于将参数写入CSV(逗号分隔值)格式的输出流中
40// 这个函数可以接受一个或多个参数,并将它们按照指定的格式输出到提供的输出流中
41template <typename Arg, typename ... Args>
42static void write_csv_to_stream(std::ostream &out, Arg &&arg, Args &&... args) {
43 // 以布尔值形式输出(true/false而不是1/0)
44 // 设置左对齐,字段宽度为44个字符
45 // 转发第一个参数到输出流中(支持左值引用和右值引用)
46 out << std::boolalpha << std::left << std::setw(44) << std::forward<Arg>(arg);
47
48 // 设置右对齐,并固定浮点数的小数点位数为2位
49 out << std::right << std::fixed << std::setprecision(2);
50
51 // 定义一个用于参数包展开的数组类型(这里实际上不会创建数组,只是利用数组初始化语法来展开参数包)
52 // 展开参数包,对每个剩余参数执行输出操作,并在参数之间添加逗号和空格作为分隔符
53 // 使用逗号表达式来同时执行输出操作和数组初始化(这里数组初始化只是为了产生编译时的副作用,即展开参数包)
54 using expander = int[];
55 (void)expander{0, (void(out << ", " << std::setw(10) << std::forward<Args>(args)), 0)...};
56}
57// 静态性能分析器类
59public:
60
61 // 构造函数,接受文件名
62 StaticProfiler(std::string filename)
63 : _filename(std::move(filename)) { // 移动构造文件名
64 logging::log("PROFILER: writing profiling data to", _filename); // 日志记录
65 std::string header = "# LibCarla Profiler "; // CSV头部信息
66 header += carla::version(); // 添加版本信息
67#ifdef NDEBUG
68 header += " (release)"; // 如果是发布模式
69#else
70 header += " (debug)"; // 如果是调试模式
71#endif // NDEBUG
72 write_to_file(std::ios_base::out, header); // 写入文件头
73 write_line("# context", "average", "maximum", "minimum", "units", "times"); // 写入列名
74 }
75
76 // 写入一行数据
77 template <typename ... Args>
78 void write_line(Args &&... args) {
79 write_to_file(std::ios_base::app|std::ios_base::out, std::forward<Args>(args)...); // 追加写入数据
80 }
81
82private:
83
84 // 向文件写入数据的私有函数
85 template <typename ... Args>
86 void write_to_file(std::ios_base::openmode mode, Args &&... args) {
87 if (!_filename.empty()) { // 确保文件名不为空
88 static std::mutex MUTEX; // 静态互斥锁
89 std::lock_guard<std::mutex> guard(MUTEX); // 加锁,保护文件写入
90 std::ofstream file(_filename, mode); // 打开文件
91 write_csv_to_stream(file, std::forward<Args>(args)...); // 写入CSV格式的数据
92 file << std::endl; // 换行
93 }
94 }
95
96 const std::string _filename; // 保存文件名
97};
98
99// 性能数据析构函数
100ProfilerData::~ProfilerData() {
101 static StaticProfiler PROFILER{"profiler.csv"}; // 静态性能分析器实例
102 if (_count > 0u) { // 如果调用次数大于0
103 if (_print_fps) { // 检查是否打印FPS
104 PROFILER.write_line(_name, fps(average()), fps(minimum()), fps(maximum()), "FPS", _count); // 写入FPS数据
105 } else {
106 PROFILER.write_line(_name, average(), maximum(), minimum(), "ms", _count); // 写入时间数据
107 }
108 } else {
109 log_error("profiler", _name, " was never run!"); // 日志错误:未运行
110 }
111}
112
113} // namespace detail
114} // namespace profiler
115} // namespace carla
void write_to_file(std::ios_base::openmode mode, Args &&... args)
Definition Profiler.cpp:86
StaticProfiler(std::string filename)
Definition Profiler.cpp:62
static void log(Args &&... args)
Definition Logging.h:61
static void write_csv_to_stream(std::ostream &out, Arg &&arg, Args &&... args)
Definition Profiler.cpp:42
static LifetimeProfiler PROFILER
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
static void log_error(Args &&... args)
Definition Logging.h:115