... Alors comme vous disiez Nicolas et toi, le compilateur sera obligé de remplir les octets pour aligner sur la taille des mots. La structure précédente risque fort d'être générée ainsi (et la norme force les compilateurs à respecter l'ordre des champs d'une structure):
structtoto_s{uint8_tf1;uint32_tf2;uint16_tf3;charpadding1[1];// alignement sur 64 bitsuint64_tf4;// déjà aligné ! uint8_tf5;charpadding2[7];// alignement sur 64 bits};
... et donc toto_s gaspille 64 bits en alignement. La bonne pratique qu'on m'a toujours indiquée (et qui ne dépend pas de l'endianness à ma connaissance), c'est de toujours trier mes champs par ordre décroissant par défaut :
structtoto_s{uint64_tf4;// déjà aligné ! uint32_tf2;uint8_tf1;uint16_tf3;uint8_tf5;// Pas besoin de padding : tous les champs sont alignés sur 64 bits !};
À ma connaissance (mais mes souvenirs datent, donc je peux me tromper), avec les champs de bit, les problèmes d'alignement sont les mêmes, avec le piège du type entier choisi pour représenter les données :
La structure foo_s utilise 17 bits, et déclare qu'ils appartiennent à un u16... et du coup il faut allouer deux u16 l'un après l'autre. Si j'avais utilisé u8, j'aurais pu potentiellement économiser 8 bits. Évidemment, dans l'exemple précédent, il faut de toute façon tenir compte du padding général, et au final, ma structure ressemblera sans doute à quelque chose de ce genre :
structfoo_s{uint64_ta1;// déjà aligné uint16_tf1:1;uint16_tf2:4;uint16_tf3:8;// fin du premier u16uint16_tf4:4;// deuxième u16charpadding1[4];};
Après, il y a toujours des trucs un peu « sioux » à faire, par exemple si le champ f1 de toto_s est partagé par plusieurs threads, il faudra sans doute rajouter du padding autour, pour éviter les problème de faux partage (false sharing), mais là ça devient sans doute un peu trop tordu...
[^] # Re: suckless !! More is less !
Posté par lasher . En réponse au journal Pourquoi un PC ralentit-il ?. Évalué à 3.
Hum, il y a quand même des « bonnes pratiques », du genre si j'ai quelque chose comme ça (en supposant une archi 64 bits) :
... Alors comme vous disiez Nicolas et toi, le compilateur sera obligé de remplir les octets pour aligner sur la taille des mots. La structure précédente risque fort d'être générée ainsi (et la norme force les compilateurs à respecter l'ordre des champs d'une structure):
... et donc
toto_sgaspille 64 bits en alignement. La bonne pratique qu'on m'a toujours indiquée (et qui ne dépend pas de l'endianness à ma connaissance), c'est de toujours trier mes champs par ordre décroissant par défaut :À ma connaissance (mais mes souvenirs datent, donc je peux me tromper), avec les champs de bit, les problèmes d'alignement sont les mêmes, avec le piège du type entier choisi pour représenter les données :
La structure
foo_sutilise 17 bits, et déclare qu'ils appartiennent à un u16... et du coup il faut allouer deux u16 l'un après l'autre. Si j'avais utiliséu8, j'aurais pu potentiellement économiser 8 bits. Évidemment, dans l'exemple précédent, il faut de toute façon tenir compte du padding général, et au final, ma structure ressemblera sans doute à quelque chose de ce genre :Après, il y a toujours des trucs un peu « sioux » à faire, par exemple si le champ
f1detoto_sest partagé par plusieurs threads, il faudra sans doute rajouter du padding autour, pour éviter les problème de faux partage (false sharing), mais là ça devient sans doute un peu trop tordu...