IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

operator new sans delete


Sujet :

C++

  1. #21
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par babar63 Voir le message
    Les deux structures crees devaient stocker deux char et un int, dans le premier cas, en laissant le compilateur aligner, la taille de la structure est de 96bits. Dans le second cas en alignant moi-meme(char unused) j'obtiens 64bits, c'est pour ca que j'ai dit que le compilateur n'alignait pas de maniere optimale...
    Dans le second cas si j'ai bien compris le pragma tu désactive l'alignement par le compilateur! Bien sûr que c'est plus compact!

    Citation Envoyé par babar63 Voir le message
    Pourquoi en bit... je travaille sur une platforme 32bits et a moins d'avoir rien compris une structure alignée signifie que la taille est multiple de 32bits...voila pourquoi, je me trompe?
    Tu n'as effectivement rien compris... désolé. Le problème c'est la notion d'alignement. L'arrangement des membres d'une structure vient après.

    Qu'est-ce que signifie "processeur 32 bits", c'est une question que je me pose depuis que je suis petit (mais à l'époque c'était surtout "console 16 bits"). En fait, cela peut vouloir dire plein de choses :
    - que les registres font x bits
    - que les registres de donnée font x bits, que l'UAL calcule sur x bits
    - que les registres d'adresse font x bits, que l'espace d'adressage fait 2**x
    - que le bus mémoire fait x bits, que x bits peuvent être écrit atomiquement dans la mémoire
    (Attention : les affirmations séparées par des virgules ne sont pas équivalentes.)

    Si tu y réfléchi, tu remarquera une discrimination implicite contre les flottants en faveur des entiers, des pointeurs, ou des registres généraux. Tu parles d'architecture 32 bits, mais sur x86 les registres flottants font 80 bits ("flottants étendus"). Pourquoi pas "processeur 80 bits"?

    Que je saches (et je ne veux pas le savoir!), certains registres généraux x86 de 32 bits se divisent en 2 registres de 16 bits utilisables indépendamment. (On a alors plus de registres, sur un processeur qui en manque cruellement.) Je défendrais donc le point de vue selon lequel c'est un processeur 16 bits.

    Mais sur ce même processeur (de très loin le plus étrange que je connaisse), il existe un multitude de façons d'adresser la mémoire (j'exagère à peine), dont un mode, je crois, permet d'adresser 48 bits. Va t-on parler de processeur 48 bits? (Ici on voit que l'espace mémoire adressable n'est pas équivalent à la taille des registres.)

    Juste pour montrer qu'on peut tout dire et son contraire.

    Plus on y réfléchi, plus on se dit que "architecture x bits", "processeur x bits" est un slogan technico-commercial qui ne veut strictement rien dire, à part que quelque part, dans le système, un traitement se fait sur x bits, ou un registre a une taille de x bits. La belle affaire!

    Après, Intel 32 bits peut être une façon de différencier les processeurs compatibles 8086 et la nouvelle architecture Intel explicitement parallèle ia64. Donc un nom de produit sans plus de signification que "mt68040" (qui n'a pas 68040 transistors).

    Revenons à nos moutons : qu'est-ce que l'alignement? Je vais prendre le cas des architecture d'ordinateurs personnels, à l'exclusion d'autres cas que tu n'es pas près de rencontrer.

    L'alignement est une contrainte qu'impose le processeur sur les accès mémoire : il veut que l'adresse utilisée pour certains accès à plusieurs octets soit alignée.

    Déjà, rappelons que l'adressage se fait au niveau des octets. C'est à dire que l'unité dans une adresse c'est l'octet : on ne peut pas désigner un bit, ou un demi-octet avec un adresse.

    Il faut savoir que, même si RAM permet la modification d'un seul octet à la fois, elle est organisée par unités de 32 ou 64 bits (selon architecture). Ce qui permet aussi de lire ou d'écrire 32 ou 64 bits d'un coup, mais à condition qu'ils soient "d'un bloc", stoqués ensemble. Par exemple, pour lire un "mot", il voudra que l'accès se fasse sur un "mot mémoire" entier, pas à cheval entre deux. Les adresses multiples de cette taille sont donc au début d'un bloc qui peut être manipulé d'un seul coup. Pour lire le même nombre de bits non-alignés sur cette frontière de "blocs", il est nécessaire de faire plusieurs accès.

    Bien sûr, tu ne travaille pas directement au niveau de la RAM mais au niveau du processeur. Lui aussi va imposer des contraintes d'alignement.

    Si tu accèdes à un "mot", mettons de 32 bits, avec une adresse qui est correctement alignée, c'est à dire qui désigne le premier octet d'un mot mémoire, le processeur n'a qu'à faire un accès à la RAM (ou au cache, peu importe). Si au contraire l'adresse ne désigne pas le premier octet d'un mot mémoire, mais, par exemple le second, et que donc la donnée se trouve à cheval sur deux mots mémoire, certains processeurs vont considérer que c'est une erreur et le système va interrompre ton programme. D'autres (dont x86) vont permettre l'accès en récupérant les deux partie de la donnée et en les assemblant si c'est une lecture, ou bien en découpant la valeur à écrire en deux et en faisant deux écritures partielles. Ceci est deux ou trois fois plus lent qu'un accès aligné, et il n'y aucun chance pour que ça s'améliore : les concepteur de processeur n'ont aucune raison d'optimiser un code qui se moque de l'alignement. (Un tel code ne cherche manifestement pas la vitesse en premier lieu.)

    Il n'est pas évident, d'ailleurs, que permettre les accès non-alignés soit un cadeau au programmeur : si ils sont le résultat d'une erreur de programmation, ou de la méconnaissance d'une notion élémentaire, mieux vaut le signaler que de tolérer, inefficacement, une telle programmation. En général, les architectures très optimisées ne vont pas s'amuser à supporter une telle programmation peu rigoureuse.

    Bon, tout ceci portait sur les processeur, et donc la programmation en assembleur; évidemment tu ne programme pas en assembleur, mais en C++. Mais le C++ permet d'utiliser les opérations de base du processeur quand on utilise les types primitifs. Ainsi, int est conçu pour correspondre à un mot processeur, qu'il fasse 16, 32, 64 ou même 36 bits! Donc la contrainte d'alignement est transposée telle-quelle en C++.

    Les types de base char, short, int , long, float double et long double sont censées correspondre à des fonctionnalité présentes dans le processeur. Les type structurés (structure, union), eux sont des outils de programmation qui n'ont pas de traduction directe fixée.

    Une structure particulière a un alignement, pour les besoins de la cause : elle a des membres, qui sont des types primitifs (ou d'autres structures, qui contiennent des types primitifs, etc.). Ce sont ces membres qui ont besoin d'être alignés. Les structures, en tant que tel, n'ont pas d'alignement particulier.

    Par exemple, il n'y a aucune raison d'aligner cette structure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    struct non_aligné {
        char seul_membre;
    };
    parce qu'un char, par définition, n'a pas d'alignement.

    Si par contre une structure possède au moins un membre qui a un alignement > 1, la structure est alignée pour que le membre le soit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    struct struct_alignée {
        int seul_membre;
    };
    Sur ton système, ça va donner un alignement de 4 pour struct_alignée. Si on ajoute d'autres membres, il faudra toujours que l'alignement soit au moins 4 (ce qui veut dire multiple de 4).

    Si, sur ton système "32 bits", les int font bien 32 bits et ont un alignement de 4, les double en font 64 et je suis quasiment sûr que leur alignement préféré est de 8. De même, il me semble, pour long long (ou _int64 ou je ne sais quoi). Une structure dont un membre a une alignement de 8 devra aussi avoir un alignement de 8.

  2. #22
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Déjà un grand merci à toi pour avoir pris la peine de donner une réponse aussi détaillé

    Et puis, en effet..... j'avais rien compris du tout... et même après avoir relu ton message plusieurs fois ce n'est pas forcément évident à assimiler (enfin pour moi en tout cas)

    Si j'ai à peu près compris, le but de l'alignement et de faire correspondre les structures de données à des mots (mémoire/processeur). La taille de la structure doit quand même au final être multiple de la taille d'un mot, taille qui peut varier et dépend du processeur(Ne travaillant pas sur la RAM).

    Certains détails restent flou quand même () par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct MyStruct1
    {
    	char c;
    	int i;
    	char c2;
    };
    Le compilateur donne une taille de 12 Octets par défaut, cela signifie bien que le compilateur à aligné sur une base de 4...? Dans ce cas et si je travaille uniquement avec des données codées sur maximum 4 octets toutes mes structures seront alignées...?

    Pour ma deuxième structure en revanche je ne suis pas sur de comprendre si elle est aligné ou pas(dans mon cas) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #pragma pack( push, 1 )
    struct MyStruct2
    {
    	char c;
    	int i;
    	char c2;
    	char unused[2];
    };
    #pragma pack( pop )
    Une autre question, ce problème n'est-il posé (à la base) que par les types prédéfinis, je m'explique : en supposant qu'une structure X est bien aligné, la taille donnée est de...16 Octets..., si maintenant une autre structure Y possèdent l'élément X alors tous les éléments doivent être aligné sur 16Octets...??? Si c'est le cas ça peut vite devenir "non-négligeable" pour des structures de donnée importante (dans le sens ou il faut faire encore plus attention pour aligner ET ne pas gaspiller inutilement de la place).

    Enfin pour la route... si tout cela dépend de tout pleins de composants au niveau du hardware, un code ou toutes les structures seraient bien alignées, l'application produite est-elle supposée être aussi rapide sur d'autres machines ou les contraintes d'alignement ne seraient pas respectées?

    Encore merci pour ton aide

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Redéfinition opérateurs new et delete globaux
    Par bolhrak dans le forum C++
    Réponses: 8
    Dernier message: 30/07/2007, 11h34
  2. surdefinition operateur new et delete
    Par johjoh dans le forum C++
    Réponses: 23
    Dernier message: 08/12/2006, 10h10
  3. intrigue sur la surcharge du new et delete
    Par swirtel dans le forum C++
    Réponses: 12
    Dernier message: 07/09/2006, 15h23
  4. Segmentation fault sur new[] et delete[]
    Par Don ViP dans le forum C++
    Réponses: 4
    Dernier message: 30/04/2006, 00h29
  5. Namespace et surcharge operator new/delete
    Par ZeLegolas dans le forum C++
    Réponses: 11
    Dernier message: 26/07/2005, 13h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo