linux下gcc编译器是怎么提高程序性能的?怎么根据gcc优化结果优化代码

软件和网站开发以及相关技术探讨
回复
luzbing
帖子: 1
注册时间: 2012-11-09 16:55
系统: ubuntu 12.04.1

linux下gcc编译器是怎么提高程序性能的?怎么根据gcc优化结果优化代码

#1

帖子 luzbing » 2012-11-09 16:57

我在写一个程序后在终端
输入
gcc -Wall -O1 -o *** ***.c ***是文件名
time ./***

gcc -Wall -O2 -o *** ***.c
time ./***

gcc -Wall -O3 -o *** ***.c
time ./***
后发现时间一次比一次段,但是程序代码并没有发生变化。
那经过三次判断后怎么根据显示结果优化代码呢(我不知道写这三段代码的作用只是看着时间程序运行越来越短,不知道怎么根据运行结果优化代码)
头像
cuihao
帖子: 4793
注册时间: 2008-07-24 11:33
来自: 郑州
联系:

Re: linux下gcc编译器是怎么提高程序性能的?怎么根据gcc优化结果优化代码

#2

帖子 cuihao » 2012-11-09 22:49

编译器不会直接修改你的代码进行优化的,如果输出汇编代码就能看出差异(编译器会先把c代码转换为汇编,再编译):
源程序:

代码: 全选

#include <stdio.h>
int main()
{
    int i, sum=0;
    for (i=1; i<=10000; i++)
        sum = sum + i;
    printf("%d\n", sum);
    return 0;
}
gcc a.c -O0 -S:

代码: 全选

	.file	"a.c"
	.section	.rodata
.LC0:
	.string	"%d\n"
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp
	movl	$0, -8(%rbp)
	movl	$1, -4(%rbp)
	jmp	.L2
.L3:
	movl	-4(%rbp), %eax
	addl	%eax, -8(%rbp)
	addl	$1, -4(%rbp)
.L2:
	cmpl	$10000, -4(%rbp)
	jle	.L3
	movl	-8(%rbp), %eax
	movl	%eax, %esi
	movl	$.LC0, %edi
	movl	$0, %eax
	call	printf
	movl	$0, %eax
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (GNU) 4.7.2"
	.section	.note.GNU-stack,"",@progbits
gcc a.c -O3 -S:

代码: 全选

	.file	"a.c"
	.section	.rodata.str1.1,"aMS",@progbits,1
.LC0:
	.string	"%d\n"
	.section	.text.startup,"ax",@progbits
	.p2align 4,,15
	.globl	main
	.type	main, @function
main:
.LFB11:
	.cfi_startproc
	subq	$8, %rsp
	.cfi_def_cfa_offset 16
	movl	$50005000, %esi
	movl	$.LC0, %edi
	xorl	%eax, %eax
	call	printf
	xorl	%eax, %eax
	addq	$8, %rsp
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE11:
	.size	main, .-main
	.ident	"GCC: (GNU) 4.7.2"
	.section	.note.GNU-stack,"",@progbits
LZ可能不懂汇编语言,但应该能看出一些变化:
1. 优化过的代码变短了(不过,有时候短不一定是快……)。
2. 优化过的代码里出现了个很神奇的数字:50005000。嘛,LZ应该能猜出来,编译器越俎代庖直接计算出了结果!

编译器优化途径很多嘛,列举我知道的:
1. 清除冗余:比如删除没有使用的变量、无作用的代码之类的。
2. 预测结果:直接计算出编译时已知的量(正如上面的);判断程序数据规模,合理减小内存占用。
3. 扩展代码:拆开固定次数的循环、变为顺序结构(执行循环时代码是来回跳跃执行的,不如顺序执行效率高);内联函数。
4. 优化存储:使用CPU寄存器(速度比内存快)来储存频繁操作的变量、数据对齐储存提高读写效率。

gcc的man里面有对每个优化开关的介绍,科技英语好的话可以看看。
要想把编译器搞的优化看明白,还得学学汇编。
有些优化,比如拆循环之类的,让编译器来干就好,自己那样写会把代码弄得很乱。
求人不如求它仨: 天蓝的Wiki 屎黄的Wiki 绿
Site: CUIHAO.TK    Twitter: @cuihaoleo
Machine: Athlon64 X2 5200+ / 2x2GB DDR2-800 / GeForce GTS 450
AD: ~まだ見ぬ誰かの笑顔のために~
头像
Strange
帖子: 1824
注册时间: 2006-05-19 9:54
来自: Shanghai

Re: linux下gcc编译器是怎么提高程序性能的?怎么根据gcc优化结果优化代码

#3

帖子 Strange » 2012-11-10 9:32

一次比一次时间短只是操作系统的缓存在起作用,和gcc什么的无关的。
你对比一下几次编译出来的binary的checksum就知道了
ニンニク入れますか?
x60 with gentoo
回复