Pourquoi GCC n’optimise-t-il pas les structures?

Les systèmes exigent que certaines primitives soient alignées sur certains points de la mémoire (en octets multiples de 4, courts en octets multiples de 2, etc.). Bien sûr, ceux-ci peuvent être optimisés pour gaspiller le moins d’espace dans le rembourrage.

Ma question est la suivante: pourquoi GCC ne le fait-il pas automatiquement? L’heuristique la plus évidente (variables d’ordre de la plus grande taille à la plus petite) manque-t-elle d’une certaine manière? Est-ce qu’un code dépend de l’ordre physique de ses structures (est-ce une bonne idée)?

Je demande seulement parce que GCC est super optimisé à bien des égards, mais pas dans celui-ci, et je pense qu’il doit y avoir une explication relativement cool (à laquelle je ne suis pas conscient).

gcc ne réorganise pas les éléments d’une structure, car cela violerait le standard C. La section 6.7.2.1 de la norme C99 stipule que:

Dans un object de structure, les membres du champ non-bit et les unités dans lesquelles résident les champs de bits ont des adresses qui augmentent dans l’ordre dans lequel elles sont déclarées.

Les structures sont fréquemment utilisées comme représentations de l’ordre d’emballage des formats de fichiers binarys et des protocoles réseau. Cela casserait si cela était fait. En outre, différents compilateurs optimiseraient les choses différemment et il serait impossible de lier le code entre eux. Ce n’est tout simplement pas réalisable.

GCC est plus intelligent que la plupart d’entre nous en produisant du code machine à partir de notre code source; Cependant, je frémis s’il était plus intelligent que nous de réorganiser nos structures, car ce sont des données, par exemple, qui peuvent être écrites dans un fichier. Une structure qui commence par 4 caractères, puis un entier de 4 octets, serait inutile si elle était lue sur un autre système où GCC a décidé de réorganiser les membres de la structure.

gcc SVN a une optimisation de la réorganisation de la structure (-fipa-struct-reorg), mais cela nécessite une parsing complète du programme et n’est pas très puissant pour le moment.

Les compilateurs C n’emballent pas automatiquement les structures précisément à cause des problèmes d’alignement que vous mentionnez. Les access non liés aux limites de mots (32 bits sur la plupart des processeurs) entraînent de lourdes contraintes sur les systèmes x86 et provoquent des interruptions fatales sur les architectures RISC.

Ne pas dire que c’est une bonne idée, mais vous pouvez certainement écrire du code qui dépend de l’ordre des membres d’une structure. Par exemple, en tant que hack, les gens lancent souvent un pointeur sur une structure en tant que type de champ à l’intérieur duquel ils souhaitent accéder, puis utilisent l’arithmétique des pointeurs pour y parvenir. Pour moi, c’est une idée assez dangereuse, mais je l’ai vu utilisée, en particulier en C ++ pour forcer une variable déclarée privée à être accessible publiquement lorsqu’elle est dans une classe d’une bibliothèque tierce et qu’elle n’est pas encapsulée publiquement. Réorganiser les membres briserait tout cela.

Vous pourriez vouloir essayer le dernier tronc gcc ou, struct-reorg-branch qui est en cours de développement.

https://gcc.gnu.org/wiki/cauldron2015?action=AttachFile&do=view&target=Olga+Golovanevsky_+Memory+Layout+Optimizations+of+Structures+and+Objects.pdf