2010-03-05 14 views
8

Estoy tratando de hacer un programa compilado con GCC y utilizando los intrínsecos Qt y SSE. Parece que cuando una de mis funciones es llamada por Qt, la alineación de la pila no se conserva. He aquí un pequeño ejemplo para ilustrar lo que quiero decir:Qt, GCC, SSE y alineación de pila

#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; 
} 

Aquí está la salida:

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

Configuración:

  • Intel Core2
  • WinXP, SP3
  • GCC 4.4 (Mingw incluido en el Qt SDK 2010.01)

traté de compilar el programa de ejemplo, con las mismas opciones que los vi en el makefile Qt:

-O2 -Wall -frtti -fexceptions -mthreads 

, opciones de enlace:

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

Ahora bien, no sé en qué instrucciones para buscar Cualquier sugerencia sería apreciada. ¡Gracias!

Fabien

Respuesta

9

Puede utilizar la opción -mstackrealign de hacer eso sin añadir atributos a su código fuente:

-mstackrealign realinear la pila en la entrada. En Intel x86, la opción -mstackrealign generará un prólogo y epílogo alternativo que realineará la pila de tiempo de ejecución si es necesario. Esto admite la mezcla de códigos heredados que mantienen una pila alineada de 4 bytes con códigos modernos que mantienen una pila de 16 bytes para compatibilidad con SSE. Ver también el atributo force_align_arg_pointer, aplicable a funciones individuales.

(de the GCC docs)

+1

¡Gracias! Según http://eigen.tuxfamily.org/dox/WrongStackAlignment.html, parece que es mejor para el rendimiento usar el atributo force_align_arg_pointer. Usar -mincoming-stack-boundary = 2 podría ser otra solución (en Windows), por lo que "GCC sabe que realmente debe tener especial cuidado para respetar la alineación de 16 bytes". – Fabien

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

hizo trabajar! ¿Alguien tiene una mejor solución?

+0

¿Qué ocurre si se intenta añadir '-mms-bitfields' a las opciones del compilador? –

Cuestiones relacionadas