gpt4 book ai didi

c++ - 基本 C/C++ 解释

转载 作者:太空狗 更新时间:2023-10-29 21:45:03 24 4
gpt4 key购买 nike

我想检查计算机视觉算法的性能,最后我编写了这段基本代码,只是为了检查哪个循环最快。但我对结果没有任何解释。我通常得到的结果表明双 for 循环比简单循环快 3 倍。如果我切换这两个循环,我会得到相同的结果,这意味着第二个循环总是被优化......那么编译器做了什么样的优化?

对不起,我知道这一定是个愚蠢的问题......

ulong k = 0;
auto start = std::chrono::high_resolution_clock::now();
for( uint i = 0; i < 1000000; ++i )
{
k++;
}
auto diff = std::chrono::high_resolution_clock::now() - start;
auto t1 = std::chrono::duration_cast<std::chrono::nanoseconds>(diff);

k = 0;
start = std::chrono::high_resolution_clock::now();
for( uint i = 0; i < 1000; ++i )
{
for( uint j = 0; j < 1000; ++j )
{
k++;
}
}
diff = std::chrono::high_resolution_clock::now() - start;
auto t2 = std::chrono::duration_cast<std::chrono::nanoseconds>(diff);

CL_PRINT( "Simple: ", t1.count() );
CL_PRINT( "Double: ", t2.count() );

如果我切换两个循环,我会得到相同的结果,这意味着第二个循环始终是优化的...

请注意,CL_PRINT 只是一个用于调试目的的宏。另请注意,我使用这些选项编译代码:-O3 -msse4.1

最佳答案

这里的答案是确切的时间会有所不同。当我运行 this code在我的机器上,有时第一个循环会出现 1000,有时第二个循环会出现 1000。当计时器滴答作响时,这只是“运气”。如果您有一个更准确的计时器,它可能会根据读取计时器所花费的时间等显示差异。

$ ./a.out
k = 1000000
k = 1000000
Simple: 0
Double: 1000
$ ./a.out
k = 1000000
k = 1000000
Simple: 1000
Double: 0
$ ./a.out
k = 1000000
k = 1000000
Simple: 1000
Double: 0
$ ./a.out
k = 1000000
k = 1000000
Simple: 1000
Double: 0

很容易看出两个循环都被优化掉了:

main:
.LFB1474:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
pushq %rbx
.cfi_def_cfa_offset 24
.cfi_offset 3, -24
subq $8, %rsp
.cfi_def_cfa_offset 32
call _ZNSt6chrono12system_clock3nowEv
movq %rax, %rbx
call _ZNSt6chrono12system_clock3nowEv
movl $.LC0, %esi
**subq %rbx, %rax**
movl $_ZSt4cout, %edi
imulq $1000, %rax, %rbp
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
**movl $1000000, %esi**
movq %rax, %rdi
call _ZNSo9_M_insertImEERSoT_
movq %rax, %rdi
call _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
call _ZNSt6chrono12system_clock3nowEv
movq %rax, %rbx
call _ZNSt6chrono12system_clock3nowEv
movl $.LC0, %esi
**subq %rbx, %rax**
movl $_ZSt4cout, %edi
imulq $1000, %rax, %rbx
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
**movl $1000000, %esi**
movq %rax, %rdi
call _ZNSo9_M_insertImEERSoT_
movq %rax, %rdi
call _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
movl $.LC1, %esi
movl $_ZSt4cout, %edi
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movq %rbp, %rsi
movq %rax, %rdi
call _ZNSo9_M_insertIlEERSoT_
movq %rax, %rdi
call _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
movl $.LC2, %esi
movl $_ZSt4cout, %edi
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movq %rbx, %rsi
movq %rax, %rdi
call _ZNSo9_M_insertIlEERSoT_
movq %rax, %rdi
call _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
addq $8, %rsp
.cfi_def_cfa_offset 24
xorl %eax, %eax
popq %rbx
.cfi_def_cfa_offset 16
popq %rbp
.cfi_def_cfa_offset 8
ret

您可以清楚地看到 K 的常量被作为常量插入到流中,并且“之前”和“之后”的时间被取出然后减去,中间没有(很多)代码。 (“有趣的”位标有 ** ... ** - 当然它不会在代码中加粗)

关于c++ - 基本 C/C++ 解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18462581/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com