GCC Vector-Extensions: misterioeser Segfault
-
Hiho!
Ich spiel grad ein wenig mit der GCC Vector-Extensions. Ich verwende den GCC 4.2.1 unter Windows. Ich hab eine Klasse fuer 3D-Vektoren, die zur Zeit so ausschaut:#define USE_GCC_VECTORISATION (defined(__SSE__) && 1) class Vector3D { public: /* * ... die ueblichen Operatoren */ private: #if USE_GCC_VECTORISATION typedef float v4sf __attribute__ (( vector_size(4 * sizeof(float)) )); typedef int v4si __attribute__ (( vector_size(4 * sizeof(int)) )); union { float v[4]; v4sf vec; }; Vector3D(const v4sf& v); #else float v[3]; #endif };Ohne die Vector-Extensions funktioniert mein Programm problemlos. MIT Vektorisierung hingegen erhalte ich prompt beim ersten Aufruf einen Segfault (ich glaub das ist die erste Vector3D-Funktion, die im ganzen Programm aufgerufen wird):
inline const Vector3D operator-(const Vector3D& lhs, const Vector3D& rhs) { #if USE_GCC_VECTORISATION return Vector3D(lhs.vec - rhs.vec); #else Vector3D retval(lhs); retval -= rhs; return retval; #endif }Oder genauer gesagt:
Frame function: operator-(Vector3D const&, Vector3D const&) (src/Vector3D.cpp:138) Frame address : 0x0022FA60 -------------------------------------------------------------------------------- 0x4f07d0 push %ebp 0x4f07d1 mov %esp,%ebp 0x4f07d3 push %ebx 0x4f07d4 sub $0x1c,%esp 0x4f07d7 mov 0x8(%ebp),%ebx 0x4f07da mov %ebx,%edx 0x4f07dc mov 0xc(%ebp),%eax 0x4f07df movaps (%eax),%xmm1 ; <<<<----- hier passiert der Segfault 0x4f07e2 mov 0x10(%ebp),%eax 0x4f07e5 movaps (%eax),%xmm0 0x4f07e8 movaps %xmm1,%xmm2 0x4f07eb subps %xmm0,%xmm2 0x4f07ee movaps %xmm2,%xmm0 0x4f07f1 movaps %xmm0,0xffffffe8(%ebp) 0x4f07f5 lea 0xffffffe8(%ebp),%eax 0x4f07f8 mov %eax,0x4(%esp) 0x4f07fc mov %edx,(%esp) 0x4f07ff call 0x46cefc <Vector3D::Vector3D(float __vector const&)> 0x4f0804 mov %ebx,%eax 0x4f0806 add $0x1c,%esp 0x4f0809 pop %ebx 0x4f080a pop %ebp 0x4f080b ret $0x4Wenn ich mir die Werte der einzelnen Komponenten von rhs/lhs im Debugger anschaue, schaut soweit eigentlich alles vollkommen normal aus. EAX enthaelt zu dem Zeitpunkt genau die Adresse von lhs (Ich verstehe zwar nur ein paar Brocken ASM, aber der generierte Code schaut auch nicht fehlerhaft aus).
Wenn ich die Klasse allerdings ausserhalb meines Projektes verwende (also z. B. versuche, einen minimalen Testcase zusammenzustellen), funktioniert komischerweise alles einwandfrei. z. B. funktioniert folgendes absolut fehlerfrei (und gibt den richtigen Wert aus):
#include "Vector3D.h" int main ( int argc, char** argv ) { // dies ist ziemlich genau das, was im Original-Quelltext beim segfault getan wird: Vector3D a(-4, -3, 10); Vector3D b(-4, 5, 10); Vector3D c = a - b; std::cout << c << std::endl; return 0; }Hat irgendwer eine Ahnung, wo der Fehler stecken koennte?
EDIT: ich meinte natuerlich Vector-Extensions, nicht Auto-Vectorisation
-
Disclaimer: Ich kenne mich mit SSE und Auto-Vec nicht so gut aus. Aber ich versuch es mal
1. Bei SSE müssen die Daten 16 byte aligned sein. Kümmert sich vector_size darum? (Kenne nur als Attribute altivec(...) für PPCs AltiVec)
2. Musste man MMX/SSE nicht mit einem Befehl erst initialisieren? Schau vielleicht mal ob dafür Code generiert wird (obwohl das dürfte eher ein SIGFPE oder so geben)
im Zweifelsfall solltest du dich mal an die GCC Leute wenden (zB #gcc auf OFTC oder per Mailingliste).
-
rüdiger schrieb:
im Zweifelsfall solltest du dich mal an die GCC Leute wenden (zB #gcc auf OFTC oder per Mailingliste).
Mailingliste.. vielleicht. Aber #gcc?! Nein!! Der Channel ist nur für die Entwicklung... :p
(War da ja schon ab und zu mit diversen G++-Bugs. :D)
-
rüdiger schrieb:
1. Bei SSE müssen die Daten 16 byte aligned sein. Kümmert sich vector_size darum? (Kenne nur als Attribute altivec(...) für PPCs AltiVec)
Davon gehe ich aus, zumindest wurde in allen Beispielen, die ich bisher zu Auto-Vectorisation gefunden hab, nie eine eigene Align-Anweisung verwendet.
2. Musste man MMX/SSE nicht mit einem Befehl erst initialisieren? Schau vielleicht mal ob dafür Code generiert wird (obwohl das dürfte eher ein SIGFPE oder so geben)
Glaub ich nicht, sonst muesste das 2te Beispiel auch nicht funktionieren.
im Zweifelsfall solltest du dich mal an die GCC Leute wenden (zB #gcc auf OFTC oder per Mailingliste).
OFTC?
Jedenfalls wollt ich erstmal hier nachfragen, nicht dass ich am Ende nur was ganz Triviales vergessen hab