为什么使用LTO会增加Rust二进制文件的大小?

时间:2018-09-12 08:43:10

标签: rust compiler-optimization lto

简介

我完成了一个小的Rust项目(大约300行代码),该项目具有以下依赖性:

问题

在不进行进一步配置的情况下使用cargo build --release时,将生成2.942.744字节(= 2,8 MiB)二进制文件。我试图通过在Cargo.toml中启用链接时间优化(LTO)来对此进行优化:

[profile.release]
lto = true

令我惊讶的是,二进制文件不断增长,其新大小为3.848.288字节(= 3,7 MiB)。

这怎么解释?我在配置货运时犯了什么错误?

2 个答案:

答案 0 :(得分:19)

什么是LTO?

LTO表示链接时间优化。通常将其设置为使用常规的优化过程来生成目标文件,而不是在链接时使用。

为什么重要?

编译器并没有针对速度超过大小或大小超过速度进行内在优化。因此LTO也没有。

相反,在调用编译器时,用户将选择一个配置文件。对于rustc

  • O0O1O2O3正在优化速度。
  • OsOz正在优化尺寸。

LTO可以组合在任何优化级别之上,并且将遵循所选的配置文件。

那为什么尺寸增加了?

默认情况下,[release]配置文件指示cargorustcO2调用O3尝试进行优化速度超过尺寸。

尤其是O3可以非常依赖内联。内联就是要为优化器提供更多的上下文,从而提供更多的优化机会... LTO提供了更多的机会来应用内联(更多已知的函数),并且这里似乎发生了更多的内联。

那为什么this blog post声称它减小了尺寸?

它也减小了尺寸。可能。

通过提供更多的上下文,优化器/链接器可以意识到部分代码或依赖项根本没有使用,因此可以省略。

如果使用OsOz,则尺寸肯定会减小。

如果使用O2O3,则删除未使用的代码,而内联会添加更多代码,因此最终结果是较大还是较小是完全不可预测的。

LTO吗?

LTO为优化器提供了更好的优化机会,因此它是Releases的很好默认值。

请记住,默认情况下,cargo倾向于速度超过尺寸,如果这不适合您,则可能需要选择另一个优化方向。

答案 1 :(得分:5)

可能是因为内联,它可以增加代码大小以提高速度。