【问题标题】:cmake: compilation statisticscmake:编译统计
【发布时间】:2011-08-23 04:01:01
【问题描述】:

我需要弄清楚哪些翻译单元需要重组以缩短编译时间,如何使用 cmake 为我的翻译单元掌握编译时间?

【问题讨论】:

  • 我一直认为cmake 只会为原生构建系统(make、nmake 等)生成 conf 文件。所以 cmake 实际上并不参与编译/链接过程。也许你应该在你的原生构建系统中寻找这样的选项。
  • 嗯,这是一个很常见的用例。但是,如果您知道如何为标准的 linux make 做到这一点,那将是最有帮助的。
  • 不幸的是,我不知道有任何 make 选项可以实现这一点。我想到的第一个解决方案是修改Makefiles,为每个gcc 命令调用time
  • 谢谢 beduin,再多一点,你就可以完成它作为答案:D

标签: c++ compilation cmake build-tools


【解决方案1】:

以下属性可用于计时编译器和链接器调用:

这些属性可以全局设置,每个目录和每个目标。这样,您只能有一部分目标(例如测试)受到此属性的影响。您还可以为每个目标设置不同的“启动器”,这也很有用。

请记住,直接使用“时间”是不可移植的,因为此实用程序并非在 CMake 支持的所有平台上都可用。但是,CMake 在其command-line tool mode 中提供了“时间”功能。例如:

# Set global property (all targets are impacted)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time")
# Set property for my_target only
set_property(TARGET my_target PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time")

CMake 输出示例:

[ 65%] Built target my_target
[ 67%] Linking C executable my_target
Elapsed time: 0 s. (time), 0.000672 s. (clock)

请注意,从 CMake 3.4 开始,只有 Makefile 和 Ninja 生成器支持此属性。

另请注意,从 CMake 3.4 开始,cmake -E time 在参数中存在空格问题。例如:

cmake -E time cmake "-GUnix Makefiles"

将被解释为:

cmake -E time cmake "-GUnix" "Makefiles"

我提交了解决此问题的patch

【讨论】:

  • 接受的答案对我不起作用,但这个对我有用。
  • 这还有一个问题:${CMAKE_COMMAND} 在窗口上有空格,无法按建议工作
  • @Pavel 你可以加引号:set_property(TARGET my_target PROPERTY RULE_LAUNCH_COMPILE "\"${CMAKE_COMMAND}\" -E time")
  • 我正在尝试使用它来调用我自己的脚本(它应该在纪元中给出开始/结束时间戳),但由于某种原因它不起作用。 (使用time 确实如此)。 set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E ${CMAKE_CURRENT_SOURCE_DIR}/myscript") 我的脚本看起来就像 #!/bin/sh $* 失败:CMake 错误:cmake 版本 3.14.5 用法:/usr/bin/cmake -E [arguments...] 可用命令:...(帮助) 有什么想法吗?
  • 这很好用,除非构建在多个线程中进行,然后就不清楚文件名和时间之间的关系是什么,因为它们是由所有线程混合而成的。有办法解决吗?
【解决方案2】:

我希望将编译器(和/或链接器)替换为“time original-cmd”。使用简单的“make”,我会说:

make CC="time gcc"

“时间”程序将运行命令并报告它所用的时间。等效机制适用于“cmake”。如果您需要捕获命令以及时间,那么您可以编写自己的命令,类似于时间(shell 脚本会这样做),以您想要的方式记录您想要的数据。

【讨论】:

  • 通常time是内置命令。要使用详细模式,需要输入make CC="/usr/bin/time -v gcc" 命令。
  • 对于 CMake 生成的 make 文件,您不能以这种方式传递编译器。一般来说,它不起作用。
【解决方案3】:

为了扩展之前的答案,这是我刚刚写的一个具体的解决方案——也就是说,它在实践中肯定有效,不仅仅是理论上,但它只被一个人使用了大约三分钟,所以它可能有一些不恰当的地方。

#!/bin/bash
{ time clang "$@"; } 2> >(cat <(echo "clang $@") - >> /tmp/results.txt)

我把上面两行放在/tmp/time-clang里然后跑了

chmod +x /tmp/time-clang
cmake .. -DCMAKE_C_COMPILER=/tmp/time-clang
make

您可以使用 -DCMAKE_CXX_COMPILER= 以完全相同的方式挂钩 C++ 编译器。

  • 我没有使用 make -j8,因为我不希望结果以奇怪的方式交错。

  • 我不得不在我的脚本中添加一个明确的 hashbang #!/bin/bash,因为 Ubuntu 12.04 上的默认 shell(我认为是 dash?)对这些重定向运算符不满意。

    李>

【讨论】:

  • 这对我很有用,谢谢!但是,我正在尝试(并且正在努力)仅从time 中提取real 输出,并将其与clang 命令在一行上 打印到results.txt?跨度>
【解决方案4】:

我认为最好的选择是使用:

set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "time -v")
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "time -v")

尽管上面说了:

请记住,直接使用“时间”是不可移植的,因为此实用程序并非在 CMake 支持的所有平台上都可用。但是,CMake 提供了“时间”... https://stackoverflow.com/a/34888291/5052296

如果您的系统包含它,使用-v 标志您将获得更好的结果。

例如

time -v  /usr/bin/c++     CMakeFiles/basic_ex.dir/main.cpp.o  -o basic_ex 
    Command being timed: "/usr/bin/c++ CMakeFiles/basic_ex.dir/main.cpp.o -o basic_ex"
    User time (seconds): 0.07
    System time (seconds): 0.01
    Percent of CPU this job got: 33%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.26
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 16920
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 6237
    Voluntary context switches: 7
    Involuntary context switches: 23
    Swaps: 0
    File system inputs: 0
    File system outputs: 48
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多