2010-03-05 3 views
8

Je suis en train de faire un programme compilé avec GCC et en utilisant les intrinsèques Qt et SSE. Il semble que lorsqu'une de mes fonctions est appelée par Qt, l'alignement de la pile n'est pas conservé. Voici un petit exemple pour illustrer ce que je veux dire:Qt, GCC, SSE et l'alignement de la pile

#include <cstdio> 
#include <emmintrin.h> 
#include <QtGui/QApplication.h> 
#include <QtGui/QWidget.h> 


class Widget: public QWidget { 
public: 
    void paintEvent(QPaintEvent *) { 
     __m128 a; 
     printf("a: 0x%08x\n", ((void *) &a)); 
    } 
}; 


int main(int argc, char** argv) 
{ 
    QApplication application(argc, argv); 
    Widget w; 
    w.paintEvent(NULL); // Called from here, my function behaves correctly 
    w.show(); 
    w.update(); 
    // Qt will call Widget::paintEvent and my __m128 will not be 
    // aligned on 16 bytes as it should 
    application.processEvents(); 

    return 0; 
} 

est ici la sortie:

a: 0x0023ff40 // OK, that's aligned on 16 bytes 
a: 0x0023d14c // Not aligned! 

Configuration:

  • Intel Core2
  • Windows XP, le Service Pack 3
  • GCC 4.4 (Mingw inclus dans le Qt SDK 2010.01)

J'ai essayé de compiler le programme exemple avec les mêmes options que celles que je voyais dans le makefile Qt:

-O2 -Wall -frtti -fexceptions -mthreads 

, options de lien:

-enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-s -mthreads 

Maintenant, je ne sais pas où directions à rechercher. Tous les indices seraient appréciés. Merci!

Fabien

Répondre

9

Vous pouvez utiliser l'option -mstackrealign de le faire sans l'ajout d'attributs à votre code source:

-mstackrealign réaligner la pile à l'entrée. Sur l'Intel x86, l'option -mstackrealign génère un prologue et un épilogue alternatif qui réaligne la pile d'exécution si nécessaire. Cela prend en charge le mélange de codes hérités qui conservent une pile alignée de 4 octets avec des codes modernes qui conservent une pile de 16 octets pour la compatibilité SSE. Voir aussi l'attribut force_align_arg_pointer, applicable aux fonctions individuelles.

(de the GCC docs)

+1

Merci! Selon http://eigen.tuxfamily.org/dox/WrongStackAlignment.html, il semble qu'il soit préférable d'utiliser l'attribut force_align_arg_pointer pour les performances. L'utilisation de -mincoming-stack-boundary = 2 pourrait être une autre solution (sous Windows), de sorte que "GCC sait qu'il faut vraiment faire très attention pour respecter l'alignement de 16 octets". – Fabien

4
__attribute__((force_align_arg_pointer)) void paintEvent(QPaintEvent *); 

fait le travail! Est-ce que quelqu'un a une meilleure solution?

+0

Qu'advient-il si vous essayez d'ajouter '-mms-bitfields' aux drapeaux du compilateur? –

Questions connexes