10
votes

Quel alignement utilise-t-il

Je développe une bibliothèque générale qui utilise Win32's Healhalloc

MSDN ne mentionne pas les garanties d'alignement de Win32's Heaphoc, mais j'ai vraiment besoin de savoir quel alignement il utilise, afin que je puisse éviter un rembourrage excessif.

sur ma machine (Vista, X86), toutes les allocations sont alignées à 8 octets. Est-ce vrai pour d'autres plates-formes aussi?


3 commentaires

Si MSDN ne le dit pas, alors Il n'y a aucune garantie . Même si vous demandez à 1000 personnes et qu'ils déterminent tous qu'il est 8 octets sur leur machine, ce n'est pas une garantie, et vous ne devriez probablement pas compter sur elle.


Je serais d'accord avec la déclaration ci-dessus. Vous voudrez peut-être regarder blogs.msdn.com/oldnewthing/oldning Archive / 2007/12/27/6873648.aspx pour voir si elle est pertinente cependant.


Je suis d'accord, il n'y a pas de garantie, mais je ne demande pas de garanties ici: je demande une expérience. Je suis confiant que Microsoft ne diminuera jamais l'alignement inférieur à 8 octets, car le double ne sera plus lisible. J'aimerais juste savoir que c'est aussi vrai pour les plates-formes embarquées.


4 Réponses :


0
votes

L'alignement sera tel que l'adresse retournée puisse être distribuée à un pointeur de tout type. Sinon, vous ne pourrez pas utiliser la mémoire dans votre application.


4 commentaires

Si je comprends bien votre réponse, le fait que l'adresse retournée puisse être modifiée à un pointeur de tout type n'est pas liée à l'alignement de la mémoire allouée.


@Matteo: c'est lié. S'il n'a pas été aligné sur un type T, un casting à t * serait invalide (il serait compilé, mais il ne serait pas garanti de travailler). Donc, comme il peut être jeté à n'importe quel type, il doit être aligné assez strictement pour travailler avec n'importe quel type.


Ok, j'ai compris votre réponse d'une autre manière, alors ce que j'ai dit avant de ne pas s'appliquer; Néanmoins, le système d'exploitation ne peut pas garantir qu'il est aligné sur n'importe quel type , sinon seulement un pointeur NULL serait OK :). Il est probablement garanti de travailler pour le plus gros type qui nécessite un alignement connu des personnes qui ont écrit l'allocator (ou au plus grand type qui nécessite un alignement que les personnes qui ont écrit l'allocator sont disposées à soutenir directement).


Malheureusement, cette garantie n'est pas valide: sur Vista32, l'alignement est de 8 octets, qui convient aux doubles et longs longs, mais il ne convient pas aux types intrinsèques SSE, qui nécessitent 16 alignements d'octets, il faut donc aligner manuellement ce.



6
votes

Étonnamment, Google se présente de preuve que healhalloc n'est pas toujours conforme à la SSE:

Heauplalloc () a tous les objets toujours alignés sur 8 octets, peu importe la taille de leur taille (mais pas 16 octets alignés, pour SSE).

Le message est à partir de la mi-2008, suggérant que Windows XP récente souffre de ce bogue.

Voir aussi http://support.microsoft.com/kb/286470 :

Les gestionnaires de tas de Windows (toutes les versions) ont toujours garanti que les allocations de tas ont une adresse de démarrage alignée sur 8 octets (sur des plates-formes 64 bits que l'alignement est de 16 octets).


2 commentaires

Oui, les types SSE vivent une sorte d'existence d'ombre où leur alignement est rarement respecté par des fonctions d'allocation. Je ne sais pas pourquoi, mais il semble être le cas sur Windows et Linux. Par défaut, vous n'obtenez pas de meilleures garanties d'alignement que 8 octets.


@jalf: étrange! Je me souviens de 1999 Lorsque Altivec a été introduit, Apple a immédiatement respecsifié leurs fonctions d'allocation newptr et newhandle pour alignement de 16 octets. Ce n'est pas comme si vous cassez de vieux logiciels de cette façon!



2
votes

La fonction HEAUPALLOC ne spécifie pas les garanties d'alignement de la page MSDN, mais je suis enclin à penser qu'il devrait avoir les mêmes garanties de globallalloc, qui est garantie de renvoyer la mémoire 8 octets alignée (bien que comptez sur des caractéristiques sans papiers. est le mal); Après tout, il est explicitement dit que Global / localALLOCC ne sont que des emballages autour de HealPalLoc (bien qu'ils puissent jeter les premiers n octets pour obtenir une mémoire alignée - mais je pense que c'est très peu probable).

Si vous voulez vraiment être sûr, utilisez simplement GloballalLoc, voire Virtualalloc, dont la granularité est la granularité de la page, qui est généralement de 4 Ko (IIRC), mais dans ce cas pour les petites allocations, vous perdrez beaucoup de mémoire. .

Au fait, si vous utilisez un nouvel opérateur C ++, vous êtes assuré de la mémoire de la mémoire alignée correctement pour le type que vous avez spécifié: Cela pourrait être le moyen d'aller.


0 commentaires

1
votes

Alignement du tas AMD64 est documenté ici:

https: // docs .microsoft.com / fr-US / CPP / Build / x64-Calling-Convention? View = MSVC-160

... Le pointeur de pile et la mémoire MALLOC ou ALLOCA, qui sont 16 octets alignés sur la performance de l'aide.


0 commentaires