web-dev-qa-db-fra.com

Pourquoi l'utilisation de LTO augmente-t-elle la taille de mon Rust binaire?

Introduction

J'ai terminé un petit projet Rust (environ 300 lignes de code) avec les dépendances suivantes:

Problème

Lors de l'utilisation de cargo build --release sans autre configuration, un binaire de 2,942,744 octets (= 2,8 MiB) est généré. J'ai essayé d'optimiser cela en activant Link Time Optimization (LTO) dans mon Cargo.toml:

[profile.release]
lto = true

À ma grande surprise, le binaire grandit, avec une nouvelle taille de 3 848 288 octets (= 3,7 Mio).

Comment cela peut-il être expliqué? Y a-t-il une erreur que j'ai commise en configurant Cargo?

16
PEAR

Qu'est-ce que le LTO?

LTO signifie Link-Time Optimization. Il est généralement configuré pour utiliser les passes d'optimisation régulières utilisées pour produire des fichiers objets ... au moment du lien à la place, ou en plus.

Pourquoi est-ce important?

Un compilateur n'optimise pas intrinsèquement la vitesse par rapport à la taille ou la taille par rapport à la vitesse; et donc non plus LTO.

Au lieu de cela, lors de l'appel du compilateur, l'utilisateur sélectionne un profil. Pour rustc:

  • O0, O1, O2 et O3 optimisent la vitesse.
  • Os et Oz optimisent la taille.

Le LTO peut être combiné au-dessus de n'importe quel niveau d'optimisation et suivra le profil sélectionné.

Alors pourquoi la taille a-t-elle augmenté?

Par défaut, le [release] profile demande à cargo d'appeler rustc avec O2 ou O3, qui tente d'optimiser la vitesse par rapport à la taille.

En particulier, O3 peut dépendre assez fortement de l'inlining. L'inlining consiste à donner plus de contexte à l'optimiseur, et donc plus d'opportunités d'optimisation ... LTO offre plus de chances d'appliquer l'inlining (fonctions plus connues), et ici il semble que plus d'inlining s'est produit.

Alors pourquoi ce billet de blog a-t-il déclaré qu'il avait une taille réduite?

Il réduit également la taille. Peut-être.

En donnant plus de contexte, l'optimiseur/éditeur de liens peut se rendre compte que certaines parties du code ou des dépendances ne sont pas utilisées du tout, et peuvent donc être élidées.

Si vous utilisez Os ou Oz, la taille est presque certaine de baisser.

Si vous utilisez O2 ou O3, le code inutilisé est supprimé tandis que l'inline ajoute plus de code, il est donc assez imprévisible que le résultat final soit plus grand ou plus petit.

Alors, LTO?

LTO donne à l'optimiseur une meilleure opportunité d'optimisation, c'est donc une bonne valeur par défaut pour les versions.

N'oubliez pas que cargo penche vers la vitesse par rapport à la taille par défaut, et si cela ne vous convient pas, vous pouvez sélectionner une autre direction d'optimisation.

26
Matthieu M.

Probablement à cause de l'inline, ce qui peut augmenter la taille du code pour augmenter la vitesse.

5
user541686