J'utilise MINGW64 Build basé sur GCC 4.6.1 pour la cible Windows 64bit. Je joue avec les nouvelles instructions d'AVX d'Intel. Mes arguments de ligne de commande sont Mais j'ai commencé à courir dans des erreurs de défaut de segmentation lors de l'allocation de variables locales sur la pile. GCC utilise les mouvements alignés Comment puis-je modifier l'alignement de la pile de GCC à 32 octets? strong> p>
J'ai essayé d'utiliser éditer: em>
J'ai essayé d'utiliser -March = CineI7-AVX -MTUNE = COREI7-AVX -MAVX code>. p>
vmovaps code> et
vmovapd code> pour déplacer
__ m256 code> et
__ m256d code> autour et ces instructions nécessitent 32 octets alignement. Cependant, la pile pour Windows 64bit n'a que 16 alignements d'octets. p>
-msttackrealign code> mais en vain, car cela aligne seulement 16 octets. Je ne pouvais pas faire
__ attribut __ ((forcer_align_arg_pointer)) CODE> Travailler soit, il aligne à 16 octets de toute façon. Je n'ai pas pu trouver d'autres options de compilateur qui répondraient à cela. Toute aide est grandement appréciée. P>
-mpreferred-pile-stack-limite = 5 code>, mais GCC dit que 5 n'est pas pris en charge pour cette cible. Je suis à court d'idées. p>
3 Réponses :
J'ai exploré la question, a déposé un rapport de bogue GCC et a découvert qu'il s'agit d'un problème connexe MINGW64. Voir Bug de GCC # 49001 . Apparemment, GCC ne prend pas en charge l'alignement de la pile de 32 octets sur Windows. Cela empêche efficacement l'utilisation d'instructions AVX 256 bits.
J'ai enquêté sur la manière de faire face à ce problème. La solution la plus simple et la plus blunte est de remplacer les accès à la mémoire alignée VMOVAPS / PD / DQA par des alternatives non alignées VMOVUPUPS, etc. Alors j'ai appris Python la nuit dernière (très bel outil, en passant) et retiré le script suivant qui fait le travail avec un Fichier d'assembleur d'entrée Produit par GCC: P>
import re import fileinput import sys # fix aligned stack access # replace aligned vmov* by unaligned vmov* with 32-byte aligned operands # see Intel's AVX programming guide, page 39 vmova = re.compile(r"\s*?vmov(\w+).*?((\(%r.*?%ymm)|(%ymm.*?\(%r))") aligndict = {"aps" : "ups", "apd" : "upd", "dqa" : "dqu"}; for line in fileinput.FileInput(sys.argv[1:],inplace=1): m = vmova.match(line) if m and m.group(1) in aligndict: s = m.group(1) print line.replace("vmov"+s, "vmov"+aligndict[s]), else: print line,
Pourriez-vous partager votre script de ré-rétrécissement de Prolog? En outre, comment obtenir du fichier d'assemblage (généré par -s) à un exécutable? Merci
@NobertP. La situation est-elle meilleure avec des versions ultérieures de Mingw64?
Parce que GCC semble être balayer ce bug sous le tapis (il a 6 ans!), Nous avons décidé d'aller un autre itinéraire. Une bonne pétition à l'ancienne, veuillez le signer. Changer.org/p/gnu-project-gcc- Compiler-Fix-Bug-54412
Vous pouvez obtenir l'effet que vous voulez par
Vous pouvez utiliser la même technique lorsque MALLOC () ne correspond pas de substance sur le tas de manière appropriée. p>
par exemple p> où p>
Je viens de courir dans le même problème d'avoir des défauts de segmentation lors de l'utilisation d'AVX à l'intérieur de mes fonctions. Et c'était également dû au désalignement de la pile. Compte tenu du fait qu'il s'agit d'un problème de compilateur (et des options pouvant aider ne sont pas disponibles dans Windows), j'ai travaillé autour de l'utilisation de la pile par: p>
Inlinge des fonctions / méthodes recevant / renvoyer les données AVX forte>. Vous pouvez forcer GCC à la configuration de votre fonction / méthode en ajoutant Sachez que l'utilisation de variables statiques n'est pas une sécurité du thread, comme indiqué dans la référence. Si vous écrivez une application multi-threadée, vous devrez peut-être ajouter une certaine protection pour vos chemins critiques. P> __ attribut __ ((alignement (32))) code> dans votre déclaration. Par exemple:
statique __m256i r __attribute __ ((aligné (32))) code>. P> li>
inline code> et
__ ((toujours_inline)) code> à votre prototype / déclaration de fonction. L'amélioration de vos fonctions augmente la taille de votre programme, mais elles empêchent également la fonction d'utiliser la pile (et donc, évite la question de la pile-alignement). Exemple:
inline __m256i myavxfonction (vide) __attribute __ ((toujours_inline)); code>. P> li>
ol>
Dans MacOS, le compilateur alignez tout tableau à 16 octets. GCC fait-il cela aussi sur 64 bits?
Salut. Après avoir effectué une expérience dans une machine Windows de 64B, à l'aide de GCC, j'ai constaté que le premier élément d'un tableau est aligné de 16 octets par défaut. Les autres éléments de la matrice sont alignés en fonction du type de données des éléments de la matrice. Par exemple, un tableau A de N i> caractères (1 octet large) aurait et a [ n i>] = & a [0] + n i>, Être & a [ n i>] 16 octets aligné.
Est-ce que les versions ultérieures de Mingw64 avec GCC 7.x résolvent ce problème?
Est-ce que cela signifie
__ attribut__ ((aligné (32))) code> n'est pas honoré aussi? par exemple. Si vous utilisez
__ m256 x __attribute__ ((aligné (32))) code>
Linux n'allonge pas la pile de 32 non plus. GCC ciblant Linux utilise
et -32 $,% RSP code> (ou tout alignement supérieur) pour aligner la pile dans les fonctions qui doivent renverser un
__ m256 code>,
__ m512 Code> ou tous les objets que vous avez déclarés avec
alignas (32) code> ou quelque chose de plus élevé que 16. Il semble qu'un bogue étrange que Mingw GCC n'utilise pas la même séquence pour enregistrer l'original
RSP code> et l'aligner.