为什么我的程序中的变量占用 60% 的执行时间
Why does a variable in my program use 60% of the execution time?
我正在使用gprof分析我的代码,并得到以下输出:
% cumulative self self total
time seconds seconds calls ms/call ms/call name
59.22 0.58 0.58 48 12.09 18.81 _GLOBAL__sub_I_inputHeight
inputHeight 是一个全局变量。我不知道 GLOBAL_sub_I_inputHeight 是什么意思,但它被调用了 48 次,消耗了 60% (0,6( 的执行时间。
有什么想法吗?
当你运行一个 运行一个 gprofiled 程序时,它会将数据写入一个文件,通常gmon.out
.该文件包含函数的地址,而不是名称。当您使用 gprof
实用程序读取数据时,它会使用程序中存在的调试信息解析名称。
这意味着,如果您运行程序,重新编译它并执行gprof
而不重新运行程序,则输出毫无意义。
让我们看一些行为类似的最小示例:
1 #include <iostream>
2
3 int global_int = 42;
4
5 int main(int argc, const char *argv[])
6 {
7 std::cout << "global_int = " << global_int << "n";
8 }
(gdb) bt
#0 global constructors keyed to global_int() () at global.cxx:8
#1 0x0804875d in __do_global_ctors_aux ()
#2 0x080484ec in _init ()
#3 0x080486f9 in __libc_csu_init (argc=1, argv=0xbffff0c4, envp=0xbffff0cc) at elf-init.c:79
#4 0xb7d2069c in __libc_start_main () from /lib/libc.so.6
#5 0x08048591 in _start () at ../sysdeps/i386/elf/start.S:119
这种回溯至少应该给我们一些谷歌的东西。这些是全局值的构造函数。
191 080486b1 <_GLOBAL__I_global_int>:
192 80486b1: 55 push %ebp
193 80486b2: 89 e5 mov %esp,%ebp
194 80486b4: 83 ec 18 sub $0x18,%esp
195 80486b7: c7 44 24 04 ff ff 00 movl $0xffff,0x4(%esp)
196 80486be: 00
197 80486bf: c7 04 24 01 00 00 00 movl $0x1,(%esp)
198 80486c6: e8 a6 ff ff ff call 8048671 <_Z41__static_initialization_and_destruction_0ii>
199 80486cb: c9 leave
200 80486cc: c3 ret
反汇编并没有让我们在这里变得更聪明,它调用函数__static_initialization_and_destruction_0(int,int)
然后更有趣:
171 08048671 <_Z41__static_initialization_and_destruction_0ii>:
172 8048671: 55 push %ebp
173 8048672: 89 e5 mov %esp,%ebp
174 8048674: 83 ec 18 sub $0x18,%esp
175 8048677: 83 7d 08 01 cmpl $0x1,0x8(%ebp)
176 804867b: 75 32 jne 80486af <_Z41__static_initialization_and_destruction_0ii+0x3e>
177 804867d: 81 7d 0c ff ff 00 00 cmpl $0xffff,0xc(%ebp)
178 8048684: 75 29 jne 80486af <_Z41__static_initialization_and_destruction_0ii+0x3e>
179 8048686: c7 04 24 d4 a0 04 08 movl $0x804a0d4,(%esp)
180 804868d: e8 9e fe ff ff call 8048530 <_ZNSt8ios_base4InitC1Ev@plt>
181 8048692: b8 50 85 04 08 mov $0x8048550,%eax
182 8048697: c7 44 24 08 20 a0 04 movl $0x804a020,0x8(%esp)
183 804869e: 08
184 804869f: c7 44 24 04 d4 a0 04 movl $0x804a0d4,0x4(%esp)
185 80486a6: 08
186 80486a7: 89 04 24 mov %eax,(%esp)
187 80486aa: e8 61 fe ff ff call 8048510 <__cxa_atexit@plt>
188 80486af: c9 leave
189 80486b0: c3 ret
这里重要的部分是,在 atexit(( 注册了一个函数,该函数驻留在 0x8048550
并被命名为 std::ios_base::Init::~Init()
但仅当该函数的参数0x1
和0xffff
时。然后这个函数也会调用 ctor std::ios_base::Init::Init()
它初始化使用 std::cout 所需的全局内容。
现在我们知道它在做什么,但不知道为什么。在这里,具有初始 gcc 知识的人会知道更多,但我的猜测是,这就是 gcc 确保每当调用一些代码来初始化一些全局/静态变量(在 main 之前运行(时,也会调用 I/O 子系统的 ctor,以便您始终可以在那里使用 std::cout
。
至于为什么在你的代码中经常调用它,为什么需要这么长时间,我不能说太多,也许你可以找到更多在调试器中安装一些断点。也许由于优化,这也是对该函数的一些错误说明。
- 简单C++"Hello World"程序的执行时间长
- 我使用 OpenMP 的线程越多,执行时间就越长,这是怎么回事?
- 为什么切换 for 循环的顺序会显著改变执行时间?
- cmd.exe与Powershell中C++程序的不同执行时间
- pthread执行时间比顺序执行时间差
- OpenCV 函数 cv::remap() 的执行时间更长,当程序在两者之间进入睡眠状态时
- 为什么 std::chrono 在测量循环和编译器优化的并行 OpenMP 的执行时间时不起作用?
- 我需要帮助来缩短检索 SSL 证书的执行时间
- 如何测量cudaMalloc执行时间
- c++中的执行时间和检查流状态
- 为什么for循环中的异步不能提高执行时间
- 为什么 C++ openMP 程序执行时间更长
- 测量任何 Windows 可执行文件的内存使用情况和执行时间
- 需要减少我的C++代码的执行时间
- 如何在 ubuntu 上的 php 脚本中获取程序(c,c++,java,python,php)的执行时间和内存使用量?
- 在Qt中设置pixmap时的执行时间很奇怪
- 异步控制线程执行时间
- 如何对 g++ 设置执行时间限制?
- 为什么我的程序中的变量占用 60% 的执行时间
- 变量声明如何影响执行时间