2013-02-02 9 views
5

Ich verfolgt einen Fehler auf die Verwendung eines __m128 (SSE-Vektor) als Wert in einer std :: unordered_map. Das verursacht einen Laufzeitsegmentierungsfehler mit Mingw32 g ++ 4.7.2.STL unordered_map stürzt mit __m128 Werten

Bitte beachten Sie das Beispiel unten. Gibt es einen Grund, warum dies fehlschlagen sollte? Oder könnte es einen Workaround geben? (Ich habe versucht, den Wert in einer Klasse zu verpacken, aber es hat nicht geholfen.) Danke.

#include <unordered_map> 
#include <xmmintrin.h>   // __m128 
#include <iostream> 

int main() 
{ 
    std::unordered_map<int,__m128> m; 
    std::cerr << "still ok\n"; 
    m[0] = __m128(); 
    std::cerr << "crash in previous statement\n"; 
    return 0; 
} 

Kompilierungseinstellungen: g ++ -march = native -std = C++ 11

+1

Einige verwandte lesen Sie hier: http://stackoverflow.com/questions/4424741/aligned-types-and-passing-arguments-by-value – Joe

+0

Wenn Sie eine dereferenzieren Zeiger auf einen '__m128'-Typ sind die resultierenden Lade-/Speicherfunktionen, die der Compiler ausgibt, typischerweise von der ausgerichteten Vielfalt, so dass es die inhärente Annahme macht, dass der zugrundeliegende Speicher vorhanden ist wird für den Typ wie erforderlich ausgerichtet (16-Byte-Ausrichtung in diesem Fall). Ich vermute, dass irgendwo im Container-Code ein Zeiger auf ein '__m128' dereferenziert wird und die Alignment-Annahme nicht gilt, was zu einem Segmentierungsfehler führt. Wenn Sie Ihr Programm mit einem Debugger ausführen und den Zeigerwert nach dem Absturz überprüfen, sollten Sie in der Lage sein, dies zu sehen. –

+0

Gibt es überhaupt keinen Zugriff auf 'm [0]' undefiniertes Verhalten? – hirschhornsalz

Antwort

2

C++ behandelt derzeit keine dynamische Zuordnung von überabgerichteten Typen. Bei üblichen x86-ABIs ist die Standardausrichtung 8 und __m128 hat eine Ausrichtung von 16 Byte, sodass sie überabgeteilt ist. Mit üblichen x86_64-ABIs ist die Standardausrichtung 16, was __m128 sicher macht (aber __m256 ist wiederum mit seiner 32-Byte-Ausrichtung unsicher).

Sehen Sie dieses Papier für eine mögliche Änderung in dem nächsten Standard, die Dinge „einfach funktionieren“ machen würde: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3396.htm

In der Zwischenzeit können Sie Ihr eigenes allocator, zum Beispiel basierend auf aligned_alloc (C11) angeben, posix_memalign (unix), _aligned_malloc (Microsoft), etc.

3

Es gibt 2 Ausgaben Ausrichtung in Bezug auf:

Ist das ABI sicherzustellen, dass __m128 Variablen sind immer auf der Suche ausgerichtet Stapel?

Gibt der globale Operator new den Speicher passend für den Typ __m128 zurück? d.h., gibt Speicher mit einer 16-Byte-Ausrichtung zurück.

+2

Danke für die Rückmeldung; es ist definitiv ein Ausrichtungsproblem. Es scheint, dass die STL-Container so entworfen werden sollten, dass sie die Ausrichtungsattribute der Elemente berücksichtigen. Vermutlich erfordert dies einen benutzerdefinierten Speicherzuordner? – Hugues