【发布时间】:2019-05-09 03:50:41
【问题描述】:
我正在运行一个用 C++ 编写的程序,其中 CPU 使用率是一个重要因素,并且一直在努力降低它,直到遇到意外的异常。该程序使用std::cout 行来查看性能,当我删除它时,Windows 资源监视器中程序的 CPU 使用率会以 4-6 秒的间隔急剧上升约 1 秒。
使用std::cout 行,它可以在 0-2% 的 CPU 使用率下平稳运行,没有任何峰值。删除 std::cout 行后,它以 0-2% 的 CPU 使用率运行,在 Windows 资源监视器中,CPU 使用率每隔 4-6 秒就会飙升至 25%。
有趣的是,增加正在输出的字符串的大小会降低 CPU Spike 的高度,而减小字符串的大小会增加 CPU Spike 的高度。
以下是有问题的代码行:
float engineCompletionTime = engineTimer->getEngineCompletionTime();
/* Stops CPU from spiking */
std::cout << "Engine cycle took " << engineCompletionTime << " milliseconds." << std::endl;
if (engineCompletionTime < 14.0f) {
std::this_thread::sleep_for(std::chrono::milliseconds((int)(14.0f - engineCompletionTime)));
}
编辑:感谢您最初的回复,但为了清楚起见:
当 std::cout 行在程序中时,没有 CPU 峰值。
当 std::cout 行不在程序中时,会出现 CPU 峰值。
随着 std::cout 打印的字符串大小增加,CPU 峰值的大小减小。
【问题讨论】:
-
std::cout是一个I/O操作,所以它需要硬件中断来通知完成,因此相对需要更长的时间。我觉得就是你说的那个尖刺。实际上,它并不占用 CPU 周期,而是 CPU 阻塞并等待直到 I/O 操作完成。 -
尝试将
std::endl更改为'\n'。使用endl会刷新缓冲区,如果做很多事情,比如在循环中,可能会导致 I/O 成为瓶颈。 -
Windows Resource Monitor通常是用于衡量单个小型应用程序(在数百个可能随时唤醒的潜在 Windows 服务中运行)的 CPU 使用率的可怕工具。通常最好使用分析器来发现代码中可以进一步优化的任何区域。 -
您通过打印引擎完成时间来打破量子叠加。尽管问题令人困惑:首先您说仅在 not 打印输出时观察到 cpu 峰值,但随后您说打印较大字符串时峰值较小。
-
鉴于打印字符串时没有 CPU 尖峰,字符串的大小如何影响这个不存在的尖峰的大小?
标签: c++