我知道gcc中的连接顺序对于正确确定符号很重要;但 现在我看到生成的可执行文件出现了一个奇怪的速度问题。我正在链接对象和archieves
g ++ -m32 a.o b.o ar1.a ar2.a -lm -lpthread -lcrypt -lz -pthread -o afast.out
VS
g ++ -m32 a.o ar1.a b.o ar2.a -lm -lpthread -lcrypt -lz -pthread -o aslow.out
第二个版本的运行速度慢了2倍。 b.o实际上是在ar1.a archieve中,但ar2.o引用了它,因此链接器抱怨,因此我不得不把b.o.在开始时,我将b.o一直放到链接的末尾以制作正确的依赖顺序,尽管后来发现它甚至可以在开始时工作,甚至更快。
有没有人经历过这个?目标文件链接顺序是否与规则不同?怎么会有速度影响?
使用gcc3.4.6或gcc4.1.2获得类似的结果
答案 0 :(得分:4)
根据目标代码在内存中的布局方式,可能在执行速度上存在显着差异。通常,您希望热函数靠近在一起,因此它们不会与冷函数混淆,因此Icache
和TLB
不会被冷函数污染。但是,你不太可能受此影响。
最有可能的是,您有一些符号在“快速”可执行文件中以某种方式解析,而另一种方式在“慢”可执行文件中解析。命令行matters上的归档库和目标文件的顺序,您最终可以在“快速”链接中从ar1.a
中提取一些对象,而您将从{{1}中提取等效对象在“慢”链接中。也许ar2.a
中有一些未优化的代码?
运行ar2.a
并检查两者中是否存在任何符号将是第一步。然后,您可以要求链接器生成链接映射(使用nm -A ar1.a ar2.a
)并检查这些符号实际来自两个链接的位置。