作者jimfan (jimfan)
看板C_and_CPP
标题Re: [问题] 相同型态的变数但值不同,运算量的差异?
时间Fri Sep 15 13:09:24 2017
: C
: 问题(Question):
: int a = 0, b = 0, c = 0;
: case 1:
: a = 1, b = 1;
: c = a + b;
: case 2:
: a = 100000, b = 100000;
: c = a + b;
: 宣告的变数型态相同,但值阈不同,
: 上述两个case分别的运算量会有差异吗?
类似疑问你可以用编译器将 .c 编译为组合语言看看
以我用 gcc 为例:
gcc -S int.c
输出档案 int.s,看看 int.c 为 case 1 的内容:
call ___main
movl $0, 12(%esp) # a = 0
movl $0, 8(%esp) # b = 0
movl $0, 4(%esp) # c = 0
movl $1, 12(%esp) # a = 1
movl $1, 8(%esp) # b = 1
movl 12(%esp), %edx # c = a + b
movl 8(%esp), %eax
addl %edx, %eax
movl %eax, 4(%esp)
movl $0, %eax # return 0
leave
又看看 int.c 为 case 2 时的内容:
call ___main
movl $0, 12(%esp) # a = 0
movl $0, 8(%esp) # b = 0
movl $0, 4(%esp) # c = 0
movl $100000, 12(%esp) # a = 1
movl $100000, 8(%esp) # b = 1
movl 12(%esp), %edx # c = a + b
movl 8(%esp), %eax
addl %edx, %eax
movl %eax, 4(%esp)
movl $0, %eax # return 0
leave
所用的 CPU 指令一模一样,大抵可以假设 CPU 运算需要的 clock cycle是一样的
当然,如果 movl、addl 对於 1(0x1)、100000(0x186A0)又另当别论,至少 Intel
不会对此有特别说明,你可以行 for loop 10000000(或更多)次试试。
另外,用不同编译器也许(多数)会导致不同输出,有些编译器可能不用 stack 而用
暂存器放置 a、b、c 的值,如果行 for loop 或更复杂的运算效能可能有所不同。
又另外,硬体都会导致差异。如果你用 16-bit CPU 的话...
最後,有楼主提到 optimisation,在 gcc 下如果加上 -O3 的输出变成:
_main:
LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
call ___main
xorl %eax, %eax
leave
所有 a、b、c 的运算省略了,因编译器知道他们的值根本没有牵涉输出输入,main()
基本上直接 return。
在下也非 CS 专科,如有错漏请赐教
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 14.199.97.157
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1505452167.A.E0E.html
1F:→ jimfan: 更正: 09/15 13:12
2F:→ jimfan: 如果 movl、addl 对於 1(0x1)、100000(0x186A0) 09/15 13:13
3F:→ jimfan: 所需 clock cycle不一样 <<< 09/15 13:13
4F:→ jimfan: 又另当别论 09/15 13:14
5F:推 hsiansheng: 感谢J大,我对组语完全没概念,需要先研究一下才行QQ 09/15 13:30
6F:→ jimfan: 有兴趣就成事了,加油 09/15 13:35
7F:→ enonrick: 用loop测只是在测哪一段撞到中断的次数多而以,没意义 09/15 15:28