大家好,我叫Chandler Shen,是Visual C++上海团队的开发人员。
我们在即将到来的Visual C++ 2010版本中做了一些修改,以提高链接器的性能。我首先简要介绍一下链接器,以及我们如何分析当前实现的瓶颈。稍后,我将描述我们所做的更改以及对链接器性能的影响。
我们的目标是大规模项目的链接器吞吐量完整构建场景,因为这个场景在链接器吞吐量可伸缩性方面最为重要。增量链接和较小的项目不会从我在这个博客中描述的工作中受益。
传统上,链接器的工作可以分为两个阶段:
1. Pass1:收集符号的定义(从对象文件和库)
2. Pass2:用最终地址(实际上是相对虚拟地址)修复对符号的引用,并写出最终图像。
链路时间代码生成(LTCG)
如果 /GL(全程序优化) 编译时,编译器将生成一个包含中间语言的特殊格式的对象文件。当链接器遇到这样的对象文件时,Pass1就变成了一个两阶段的过程。从这些对象文件中,链接器首先调用编译器来收集所有公共符号的定义,以构建一个完整的公共符号表。然后链接器将这个符号表提供给编译器,编译器生成最终的机器指令(或代码生成)。
调试信息
在Pass2期间,除了写入最终映像之外,如果用户指定,链接器还会将调试信息写入PDB(程序数据库)文件 /调试(生成调试信息) . 有些调试信息,例如符号的地址,在链接之前是不确定的。
在本节中,我将展示如何分析一些测试用例以找出性能瓶颈。
测试用例
为了得到一个客观的结论,我们选择了四个不同规模的实际项目(名字省略),包括proj1、proj2、proj3和proj4作为测试用例。
|
项目1 |
项目2 |
项目3 |
项目4 |
|
文件夹 |
总计 |
55 |
27 |
168 |
1066 |
对象 |
4 |
6 |
7 |
882 |
|
.lib文件 |
51 |
21 |
161 |
184 |
|
符号 |
6026 |
22436 |
69570 |
110262 |
在表1中,“符号数”是链接器内部用于存储所有外部符号信息的符号表的条目数。值得注意的是,“proj4”比其他的要大得多。
测试环境
以下是试验机的配置
· 硬件
o 中央处理器 Intel Xeon CPU 3.20GHz,4核
o 皇家音乐学院 2克
· 软件 Windows Vista 32位
结果
为了尽量减少环境的影响,所有病例都进行了5次。时间单位是秒。
在表2和表3中,它表明对于每个测试用例,总是有一个(通常是第一个,在 红色 )跑的时间比别人长得多。 当一次运行(标记为 绿色 )可能需要更短的时间。这是因为以下两个原因
我 操作系统会将文件内容缓存在内存中,以便下次读取(在WindowsXP上称为预取,等等) 超级蚀刻 在Windows Vista上)
我 大多数现代硬盘都会缓存文件内容,以便下次读取
比较表2和表3,我们可以注意到,如果关闭/debug,Pass2的时间要短得多。因此,它表明Pass2的大部分是在写PDB文件
密码1 |
密码2 |
总计 |
||
项目1 |
1 |
4.437 |
2.328 |
6.765 |
2 |
0.266 |
1.218 |
1.484 |
|
三 |
0.265 |
1.188 |
1.453 |
|
4 |
0.265 |
1.219 |
1.484 |
|
|