這是最近流行的最佳化技術之一。打破所謂的Source file隔離原則,可以在Link time時對程式作最佳化。
Without LTO
直接給個範例
1 | #include <stdio.h> |
1 | int add(int a, int b) |
按照一般的方式編譯它,用objdump觀察編譯結果。
1 | $ gcc demo.c add.c -O2 -o demo |
可以看到main被disassembler的code
1 | 400531: bf 01 00 00 00 mov edi,0x1 |
可以看到就算開了O2
最佳化之後,還是會先呼叫add,然後繼續呼叫printf。
每個Compilier的作法不一樣,因此分開介紹
LTO With GCC
GCC的方法比較簡單,所以最先介紹。只要在編義的時候加上-flto
就可以了。注意-flto的選項對-O0無效,至少要-O1以上
1 | $ gcc demo.c add.c -flto -O2 -o demo |
然後同樣看一下disassembler的code
1 | 400470: 48 83 ec 08 sub rsp,0x8 |
可以看到printf之前的add不見了,取而代之的直接算出2,然後呼叫printf。
LTO With Clang
在Linux怎麼搞兜兜搞不定,不過在OS X一次就成功了。Gold linker好難裝啊
在Clang不需要開啟任何的最佳化。
1 | $ clang -flto demo.c add.c -o demo |
LTO With VC++
測試了一下,這方法只對Release Build有用,Debug Build的行為就類似於GCC -O0一樣不會最佳化。
編譯選項在於Link-time Code Generation直接修改就能用了。