编译连接优化

最近在做exe体积优化的事情,于是把vc10编译器连接器有关的选项都过了一遍

一般情况下,使用/O1做最小体积优化

根据msdn介绍,/O1等于/Og /Os /Oy /Ob2 /Gs /GF /Gy,也就是说
/O1 会自动开启 <Global Optimization>/Og、<Favor small code>/Os、<Omit Frame Pointers> /Oy、<string pooling>/GF、/Gs(Control Stack Checking Calls)、<Enable Function-Level Linking> /Gy
并且/O1 会自动关闭 <basic runtime checks>、<smaller type checks>

这些参数作用分别是

/Og表达式合并,变量寄存器化,循环优化,nrvo

/Os优化以体积优先

/Oy令编译器编译函数时,prologue不产生push ebp; mov ebp esp,epilogue不产生pop ebp代码,函数体内不产生基于ebp寻址的代码,对调试程序有一定影响,特别是当程序使用动态栈内存分配时

/Ob2,展开inline函数

/GF,不用说了

/Gs,默认是4k,当函数栈变量大于4k时,调用_chkstk函数分配更多的栈空间

/Gy,合并相同的函数,例如不同命名空间内相同的函数、模板类的非模板函数;去除没有使用的函数

接下来需要设置以下选项,使exe体积更小
关闭<inline fuction expansion> /Ob0,禁止编译器展开标记为inline的函数,个人认为,人为的inline不可取,应更相信编译器及连接器的能力
开启<whole program optimization> /GL,用于支撑连接器/LTCG
禁止<enable c++ exceptions> no/EH,编译参数不要加上任何/EH相关的参数
禁止<buffer security check> /GS- 不插入缓冲区检查代码

缓冲区溢出检查原理,在函数栈内,返回地址与栈变量间插入4字节标记,进入函数时设置值,函数返回时检查该值是否被修改,如果被修改,就证明函数栈溢出

可参考msdn http://msdn.microsoft.com/library/aa290051.aspx
开启/Gy后,需要配合连接器 /OPT:REF /OPT:ICF
禁止<Enable Run-Time Type Information> /GR- 不使用C++ RTTI,对极少数使用dynamic_cast有影响

连接器选项
开启<merge section> /MERGE .rdata=.text 合并相同属性PE段,减少PE文件体积;不能合并不同属性段,.rsrc段必须单独存在
禁止<randomized base address> /DYNAMICBASE:NO 注意,randomized base address是vista引入的一种防御缓冲区溢出攻击的手段

根据msdn,vista开始,dll加载的地址不再是固定不变,在256个可能的地址内随机选择一个,这样做使缓冲区溢出攻击的目标地址变得不可确定。

注意,若开启这个选项,就表明这个模块支持rba,加载地址必然是随机;但不开启,并不代表加载地址不变,windows加载dll时如果地址冲突,会选择新的地址加载,这个能力由下面这个选项决定是否开启
开启<fixed base address> /FIXED 与上一个选项联合作用,使连接器不生成PE的.reloc段,减少PE文件体积;注意只针对exe,dll不应该这样设置;如果dll不支持可变基址,地址冲突时将导致dll无法加载
不支持<image has safe exception handlers> /SAFESEH:NO 不创建SEH表,safe exception handlers table是一种防御缓冲区溢出攻击的手段;注意,启用安全SEH处理表后,只有在表内登记的异常情况才允许执行异常处理例程,用于防止缓冲区溢出攻击改写异常处理例程地址。
开启<link-time code generation> <profile guided optimization> /LTCG LTCG:PGI PGO 连接器代码生成,可在模块间进行代码优化;应优先使用PGI PGO,如果条件不允许,单独使用LTCG也能得到比较好的效果

时间: 2024-11-12 06:59:58

编译连接优化的相关文章

VC编译连接选项详解(转)

大家可能一直在用VC开发软件,但是对于这个编译器却未必很了解.原因是多方面的.大多数情况下,我们只停留在“使用”它,而不会想去“了解”它.因为它只是一个工具,我们宁可把更多的精力放在C++语言和软件设计上.我们习惯于这样一种“模式”:建立一个项目,然后写代码,然后编译,反反复复调试.但是,所谓:“公欲善其事,必先利其器”.如果我们精于VC开发环境,我们是不是能够做得更加游刃有余呢? VC的处理流程,大致分为两步:编译和连接.源文件通过编译生成了.obj文件:所有.obj文件和.lib文件通过连接

VC编译连接选项详解

VC编译连接选项详解 大家可能一直在用VC开发软件,但是对于这个编译器却未必很了解.原因是多方面的.大多数情况下,我们只停留在"使用"它,而不会想去"了解"它.因为它只是一个工具,我们宁可把更多的精力放在C++语言和软件设计上.我们习惯于这样一种"模式":建立一个项目,然后写代码,然后编译,反反复复调试.但是,所谓:"公欲善其事,必先利其器".如果我们精于VC开发环境,我们是不是能够做得更加游刃有余呢? VC的处理流程,大致分

mysql优化之连接优化

Posted by Money Talks on 2012/02/23 | 第一篇 序章第二篇 连接优化第三篇 索引优化第四篇 查询优化第五篇 到实战中去 连接优化 连接优化主要指客户端连接数据库以及数据库为响应客户端的请求而打开数据表和索引的过程中涉及到的参数调整.原文可以参考这里或者这里.(原文链接 http://ddbiz.com/?p=950)尽管不同的mysql发行版本的编译和链接方式也会影响到客户端的链接请求,但是由于我的系统多是直接安装mysql的发行包,且很少会做改动,因此关于手

vc++ 编译连接错误and解决方法

1. LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol [email protected] Debug/lizi.exe : [分析]: 项目创建错误,因该选择Win32 Console Project,而不是 Win32 Projectvc++ 编译连接错误and解决方法,布布扣,bubuko.com

10 表连接优化

本章提要-----------------------------------------查询优化器要确定多张表的连接顺序和连接方法, 目的是通过尽早的过滤不需要的数据, 减少要处理的数据量.本章会介绍3种基本连接方法: 嵌套循环连接, 合并连接, 哈希连接如何选择连接放的的基本建议.----------------------------------------- 10.1 定义    连接树    数据库引擎支持的所有的连接方法都是每次只能处理两个数据集. 它们被称作 左节点 和 右节点,

Java编译期优化与运行期优化技术浅析

Java语言的“编译期”是一段不确定的过程,因为它可能指的是前端编译器把java文件转变成class字节码文件的过程,也可能指的是虚拟机后端运行期间编译器(JIT)把字节码转变成机器码的过程. 下面讨论的编译期优化指的是javac编译器将java文件转化为字节码的过程,而运行期间优化指的是JIT编译器所做的优化. 编译期优化 虚拟机设计团队把对性能的优化集中到了后端的即时编译器(JIT)中,这样可以让那些不是由javac编译器产生的class文件也同样能享受到编译器优化所带来的好处.但是java

Linux程序可以编译连接但是执行时找不到*.so 一般都和LD_LIBRARY_PATH有关

http://bbs.chinaunix.net/thread-983182-1-1.html PATH变量: 此变量代表可执行程序在任意位置直接输入指令执行时,系统会到此变量标记的目录里去找对应的可执行程序. 有些命令的路径没有在PATH环境变量中,可以用echo $PATH命令查询得知,添加路径到PATH环境变量的方法如下: (1)如果只想在本次开机过程中临时性的添加修改,下次开机就无效的话,可以: export PATH=$PATH:path -----path为命令所在路径 (2)如果只

(一)MySQL 连接优化

一.MySQL 连接优化 1.查看连接参数(show variables) mysql> show variables like '%connect%'; +-----------------------------------------------+-----------------+ | Variable_name | Value | +-----------------------------------------------+-----------------+ | characte

windows环境中利用NMake工具编译连接C++源代码

这篇文章是上一篇文章(http://www.cnblogs.com/LCCRNblog/p/4532643.html)的补充,因此需要先看看上一篇文章. 最近在写代码的时候,需要通过命令的方式来执行生成的c++源代码文件,因此需要学习有关windows环境下如何使用命令来编译连接c++原文件.这一篇文章是自己慢慢摸索实践得出的.作为自己入门的起点吧,后续还要好好深入理解这方面的知识. 1.准备 编写好main.cpp header.h header.cpp这三个源代码文件,并放入一个文件夹tes