Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Atteint de JavaScriptite Aiguë [Cyril Durand]

Expert ASP.net Ajax et WCF, Cyril Durand parle dans son blog de point techniques sur ASP.net, ASP.net Ajax, JavaScript, WCF et .net en général. Cyril est également consultant indépendant, n'hésitez pas à le contacter pour de l'assistance sur vos projets

Actualités

  • Blog de Cyril DURAND, passionné de JavaScript, Ajax, ASP.net et tout ce qui touche au developpement Web Client-Side.

    N'hésitez pas à me contacter pour vos projets .net : architecture, accompagnement, formation, ...

    View Cyril Durand's profile on LinkedIn
    hit counters


    Expertise Commerce server et BizTalk

Taille d'un Boolean en memoire

Récemment Bidou, Coq et moi nous sommes posé la question suivante : "Comment un Boolean est stocké en mémoire en C# ?"

D'instinct on a pensé 1 bit puis 1 octet puis 2 puis 4, bref on ne savait pas exactement quelle était la bonne réponse. On a donc demandé à Mitsu Furuta (Relation technique Développeurs chez Microsoft France) et voici sa réponse :


Il convient de distinguer 2 choses : La taille mémoire et l’adressage.

Un booléen est en effet une valeur binaire qui n’a besoin que d’un bit pour stocker sa valeur. Cependant, un processeur 32bits n’est capable d’adresser des adresses physiques que tous les 32bits.

En fait il peut le faire à l’octet prêt mais ira d’abord à l’adresse 32bits la plus proche et fera un offset de 0, 8, 16 ou 24bits pour avoir l’octet (un masque puis un décalage).

Conclusion :

  • C’est plus lent de lire un octet ou un double !
  • Qu’on lise 8 ou  16bits, on en lit toujours 32 !

La réponse la plus correcte pour tout le monde est qu’un booléen ne consomme que 1 octet et c’est ce que renverra sizeof en mode unsafe.

Je vais pourtant vous montrer que l’adressage peut fausser cette information.

Testons ici la taille de StructTest.

struct StructTest { bool b; }

sizeof renvoie 1

struct StructTest { bool b; int i; }

sizeof renvoie 8 !

La meilleur démo pour finir :

struct StructTest { bool b; bool b2; int i; }

sizeof renvoie toujours 8 dans ce cas, car le compilateur a pris le choix  d’aligner b et b2 dans le même 32bits.

La réponse la plus précise à mon sens est donc que la taille réellement consommée par une variable dans un programme dépend du contexte dans lequel elle est utilisée.

Allez, encore quelques astuces :

struct StructTest { bool b; bool b2; int i; }

Consomme 8 octets. 1x32bits pour les deux bool et un int32.

struct StructTest { bool b; int i; bool b2; }

Quasiment la même définition mais réordonnée : consomme 12 octets (3x32bits).

Les deux bool n’étant pas côte à côte, le compilateurs leur réserve chacun 32bits.

L’alignement par défaut de C# est séquentiel, c'est-à-dire qu’il respecte l’ordre d’écriture des champs.

On peut modifier cet alignement avec l’attribute StructLayout :

[StructLayout(LayoutKind.Auto)] struct StructTest { bool b; int i; bool b2; }

Auto optimise le regroupement de données dont la taille est inférieure à 32bits. Ainsi, les deux bools seront replacés côte à côte afin que la structure ne consomme que 8 octects. Il faut faire très attention à cette méthode lorsque l’on fait de l’intérop car l’ordre des champs n’est pas celui qu’on croit.

Enfin, [StructLayout(LayoutKind.Explicit)] vous permet de définir l’offset exact de chaque champ dans la structure (avec FieldOffset sur chaque champ).

Pour toutes ces raisons, si vous avez beaucoup de bits à manipuler, il est catastrophique d’utiliser un tableau de boolean : pour cela, il y a  classe BitArray qui ne consommera qu’un bit par booléen.

Mitsu


Encore merci Mitsu pour toutes ces explications.

Posted: samedi 13 octobre 2007 20:48 par cyril
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

richardc a dit :

Marrant: quelqu'un lors d'une formation dernièrement (neo tu dois t'en souvenir) m'a affirmé le contraire. Il était tellement sur de lui que j'ai préféré laissé tomber mais il est bon de temps en temps de retourner à son bon vieux C++ et aux Win32.

NB: ton explication n'est pas vrai sous un CPU 64bits et je pense même que selon le CPU (AMD, Intel), il y a des comportements différents.

# octobre 14, 2007 09:50

RaptorXP a dit :

StructLayout est fait à la base lorsque la structure doit être passée à des appels non managés. Il n'est pas tellement recommandé de l'utiliser sinon

# octobre 14, 2007 11:00

Mitsu a dit :

Tout à fait, en 64bits c'est différent.

StructLayout (explicit) est en effet utilisé pour mapper un espace mémoire de manière certaine lors d'appels non managés. On remarquera au contraire qu'il est préférable d'utiliser StructLayout (Auto) qu'en mode managé.

Dernière astuce: StructLayout en Explicit permet de mapper plusieurs champs sur le même offset !!!

Cela permet de mapper les champs variants dans une structure ('record case' en pascal ou 'union' en C).

A ma connaissance, c'est également la seule façon de hacker des structures mémoires non compatibles au sens CLR sans soulever d'exception et sans être en unsafe...mais tout ça reste entre nous, je ne vous ai rien dit :p.

# octobre 14, 2007 15:30

brunews a dit :

"D'instinct on a pensé 1 bit..." on mettra ça sur le compte de la fatigue.

Comme rappelé par Mitsu en d'autres termes, la plus petite unité adressable est l'octet, le bit est seulement manipulable.

struct StructTest

{

 bool b;

 int i;

}

y a des endroits où celui qui code ça ne prend pas la porte illico ?

Il est clair que ça fait 8 octets de taille, merci le compilo. Adresser DWORD à une adresse non multiple de 4 est sanctionné par une exception du CPU (que Windows rattrape en réglage par défaut) mais ça ralentit gravement. Sur CPU Alpha c'est badaboum à tout coup.

Il y a un moyen ssimple d'aligner correctement les données d'une structure, remplir du plus grand vers le plus petit.

Bidou, Coq et Cyril en stage d'ASM pour vous nettoyer le cerveau des faux concepts de l'interprété.

# octobre 14, 2007 21:12

Mitsu a dit :

Merci Bruno pour ta délicatesse habituelle, lol.

Les choix d'alignement, c'est choisir entre la consommation mémoire et la performance. C'est un peu toute l'histoire de l'informatique, même encore aujourd'hui...

# octobre 15, 2007 11:35

pat75 a dit :

Personnellement je préfère la réponse la plus correcte ;-)

La plus "précise" me parait un peu imprécise. Je crains qu'une lecture un peu rapide laisse croire que la taille de ce fameux booléen (les deux phrases ne parlent pas du booléen mais d'un autre côté on les rapproche tout de même l'une de l'autre) puisse changer selon le contexte. Je pense qu'il faudrait préciser que la taille allouée à chaque membre élémentaire est fixe mais que l'ensemble de la structure peut-être plus ou moins grande car des octets INUTILISES peuvent être insérés pour préserver un alignement efficace des données élémentaires. Ou je coupe un peu les cheveux peut-être ?

# octobre 16, 2007 20:01

FREMYCOMPANY a dit :

@pat75 : cette notion de padding est totalement vérifiée lorsque l'on travaille avec des structures native comme les menus, les stringTable, ... Le padding y est fort présent.

Mais cela n'explique que partiellement la variance des tailles.

# octobre 17, 2007 21:20

neodante a dit :

richard: pas souvenir d'une discussion sur le sujet lors de la formation (ou alors pendant les jours où je n'étais plus là ?).

# octobre 18, 2007 11:15
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01