2010-03-05 130 views
8

我試圖編寫一個用GCC編譯的程序,並使用Qt和SSE內在函數。 看來,當我的一個函數被Qt調用時,堆棧對齊不會被保留。這裏有一個簡單的例子來說明我的意思:Qt,GCC,SSE和堆棧對齊

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

下面是輸出:

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

配置:

  • 英特爾酷
  • 的WinXP,SP3
  • GCC 4.4( Mingw包含在Qt SDK 2010.01中)

我試圖用同樣的選項,這些我在Qt的makefile中看到編譯示例程序:

-O2 -Wall -frtti -fexceptions -mthreads 

,鏈接選項:

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

現在我不知道在哪個方向搜索。 任何提示將不勝感激。謝謝!

法比安斯基

回答

9

您可以使用該選項-mstackrealign做,沒有添加屬性的源代碼:

-mstackrealign 重新調整在入境堆棧。在Intel x86上,-mstackrealign選項將生成備用序幕和尾聲,以便在必要時重新對齊運行時堆棧。這支持將保留4字節對齊堆棧的傳統代碼與保留16字節堆棧以保持SSE兼容性的現代代碼混合。另請參見屬性force_align_arg_pointer,適用於各個功能。

(從the GCC docs

+1

謝謝! 根據http://eigen.tuxfamily.org/dox/WrongStackAlignment.html,似乎使用force_align_arg_pointer屬性的性能更好。使用-mincoming-stack-boundary = 2可能是另一種解決方案(在Windows上),因此「GCC知道它確實必須格外小心才能遵守16字節對齊」。 – Fabien 2010-03-08 11:19:57

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

使工作!有沒有人有更好的解決方案?

+0

,如果你嘗試加入'-mms-bitfields'到編譯器標誌,會發生什麼? – 2010-03-05 18:12:51