gcc编译(有时)会导致cpu负载不足 我有一个较大的C++程序,它是通过读取成千上万个小文本文件到内存中并在STL容器中存储数据开始的。这大约需要一分钟。编译将周期性地显示程序的初始部分将以大约22-23%的CPU负载运行的行为。一旦该步骤结束,它将返回到~100%CPU。当O2标志打开时,更可能发生这种情况,但不一致。使用-p标志时,这种情况更不常见,这使得几乎不可能分析。我确实捕获过一次,但是gprof输出没有帮助——所有东西都以相同的相对速度运行,只是cpu使用率很低
我很确定这与多核无关。我有一个四核cpu,大部分代码都是多线程的,但我在单线程上测试了这个问题。另外,当我在多个线程中运行有问题的步骤时,每个线程只运行约20%的CPU 我为这个问题的模糊性提前道歉,但是我已经没有办法进一步解决这个问题了,所以任何提示都可能有帮助gcc编译(有时)会导致cpu负载不足 我有一个较大的C++程序,它是通过读取成千上万个小文本文件到内存中并在STL容器中存储数据开始的。这大约需要一分钟。编译将周期性地显示程序的初始部分将以大约22-23%的CPU负载运行的行为。一旦该步骤结束,它将返回到~100%CPU。当O2标志打开时,更可能发生这种情况,但不一致。使用-p标志时,这种情况更不常见,这使得几乎不可能分析。我确实捕获过一次,但是gprof输出没有帮助——所有东西都以相同的相对速度运行,只是cpu使用率很低,c++,linux,gcc,cpu-usage,C++,Linux,Gcc,Cpu Usage,我很确定这与多核无关。我有一个四核cpu,大部分代码都是多线程的,但我在单线程上测试了这个问题。另外,当我在多个线程中运行有问题的步骤时,每个线程只运行约20%的CPU 我为这个问题的模糊性提前道歉,但是我已经没有办法进一步解决这个问题了,所以任何提示都可能有帮助 更新:为了确保清楚起见,代码中有问题的部分有时(约30-40%的编译)运行在100%的CPU上,因此很难相信I/O是瓶颈这一(其他合理的)论据,因为您正在读取大量小文件,所以您的程序在大多数时间都被阻止在磁盘上等待I/O。由于CPU在
更新:为了确保清楚起见,代码中有问题的部分有时(约30-40%的编译)运行在100%的CPU上,因此很难相信I/O是瓶颈这一(其他合理的)论据,因为您正在读取大量小文件,所以您的程序在大多数时间都被阻止在磁盘上等待I/O。由于CPU在等待磁盘将数据发送给它时并不繁忙,因此您看到的负载明显低于100%。一旦这一切结束,现在您就受到CPU的限制,您的程序将占用所有可用的CPU时间 事实上,它有时工作得更快是因为(正如Jarryd&DigitalRoss所提到的)一旦您将它们读入系统内存,它们就在操作系统的缓存中,因此后续加载速度会快一个数量级,除非它们被其他磁盘I/O逐出。因此,如果您背靠背运行程序,第二次运行可能会快得多。如果您等待一段时间(同时执行其他操作),可能有足够的其他磁盘I/O将这些文件从缓存中移出,在这种情况下,重新读取这些文件将需要很长时间。这是缓冲缓存
我的猜测是,你看到的是正在运作的结果 这数千个文件需要很长时间才能从磁盘读入,CPU将主要等待旋转和寻道延迟。报告的CPU使用时间将以百分比表示。(但总体而言可能更大。) 但一旦读取,这些小文件就完全缓存在内存中,访问每个文件(在后续运行中)就变成了一个纯粹的CPU限制活动
块是否保留在缓存中取决于干预活动,如重新编译。当运行新程序并读取其他文件时,程序和文件将被缓存,旧块将被删除,显然,内存密集型工作负载也会清除缓冲区缓存。除了提到缓冲区缓存的其他答案外,如果您想了解编译过程中发生的情况,您可以将以下部分内容传递给GCC(即传递给
g++
,可能作为Makefile
中的cxflags
设置):
-
<>代码> -v>代码>,请参阅<代码> g++<代码>,以显示相关子过程(例如,C++代码编译器的代码> cc1Pule<代码>)
要求-time
报告每个子进程的时间g++
要求-ftime report
(实际上是g++
)报告编译器内部阶段或过程的时间cc1plus
sync;echo 3>/proc/sys/vm/drop_缓存
,如下所述