Kompilierung schlägt mit OpenMP unter Mac OS X Lion fehl (memcpy und SSE intrinsics)

8

Ich bin auf das folgende Problem gestoßen. Das folgende Code-Snippet wird unter Mac OS X nicht mit einem Xcode verknüpft, den ich ausprobiert habe (4.4, 4.5)

%Vor%

Der Code wird nur als Beispiel bereitgestellt und würde bei der Ausführung segfault. Der Punkt ist, dass es nicht kompiliert. Die Kompilierung erfolgt mit der folgenden Zeile

%Vor%

Der Code wird gut kompiliert, wenn nicht mit dem -fopenmp Flag auf gcc gesetzt wird. Nun habe ich gegoogelt und eine Lösung für das erste Problem gefunden, das mit memcpy verbunden ist, welches -fno-builtin oder -D_FORTIFY_SOURCE=0 zu gcc arguments list hinzufügt. Ich habe es nicht geschafft, das zweite Problem (intrinsisch) zu lösen.

Kann mir jemand helfen, das zu lösen? Die Fragen:

  • Am wichtigsten: Wie wird der Fehler "
angainor 17.10.2012, 10:19
quelle

1 Antwort

15

Dies ist ein Fehler in der Art und Weise, wie Apples LLVM-unterstützter GCC ( llvm-gcc ) OpenMP-Regionen transformiert und Aufrufe an die darin enthaltenen Built-Ins handhabt. Das Problem kann diagnostiziert werden, indem die intermediären Baumauszüge untersucht werden (erhältlich durch Übergabe des -fdump-tree-all -Arguments an gcc ). Ohne OpenMP-Aktivierung wird die folgende endgültige Codedarstellung generiert (von test.c.016t.fap ):

%Vor%

Dies ist eine C-ähnliche Darstellung, wie der Compiler den Code intern nach allen Transformationen sieht. Dies wird dann in Montageanweisungen umgewandelt. (hier werden nur die Zeilen angezeigt, die sich auf die integrierten Funktionen beziehen)

Wenn OpenMP aktiviert ist, wird die parallele Region in die eigene Funktion main.omp_fn.0 :

extrahiert %Vor%

Auch hier habe ich nur den Code, der auf die Builtins verweist, hinterlassen. Was offensichtlich ist (aber der Grund dafür ist mir nicht sofort klar) ist, dass der OpenMP-Code trasnformer wirklich darauf besteht, alle eingebauten Funktionen über Funktionszeiger aufzurufen. Diese Zeigerzuordnungen:

%Vor%

erzeugen externe Referenzen auf Symbole, die nicht wirklich Symbole sind, sondern Namen, die vom Compiler speziell behandelt werden. Der Linker versucht dann, sie aufzulösen, kann jedoch keinen der __builtin_* - Namen in einer der Objektdateien finden, mit denen der Code verknüpft ist. Dies ist auch in dem Assembler-Code zu beobachten, den man erhalten kann, indem man -S an gcc :

übergibt %Vor%

Dies ist im Grunde ein Funktionsaufruf, der 3 Argumente benötigt: eine Ganzzahl in %eax und zwei XMM-Argumente in %xmm0 und %xmm1 , wobei das Ergebnis in %xmm0 zurückgegeben wird (gemäß der SysV AMD64 ABI-Funktion) Aufrufkonvention). Im Gegensatz dazu ist der Code, der ohne -fopenmp generiert wird, eine Erweiterung auf Befehlsebene des intrinsischen Systems, wie es geschehen soll:

%Vor%

Was passiert, wenn Sie -D_FORTIFY_SOURCE=0 übergeben, ist, dass memcpy nicht durch die "verstärkte" Prüfversion ersetzt wird und stattdessen ein regulärer Aufruf von memcpy verwendet wird. Dadurch werden die Verweise auf object_size und __memcpy_chk entfernt, der Aufruf des integrierten ia32_shufpd kann jedoch nicht entfernt werden.

Dies ist offensichtlich ein Compilerfehler. Wenn Sie wirklich wirklich den GCC von Apple verwenden müssen, um den Code zu kompilieren, dann wäre eine Übergangslösung, den fehlerhaften Code in eine externe Funktion zu verschieben, da der Fehler anscheinend nur Code betrifft, der aus parallel regions extrahiert wird:

%Vor%

Der Overhead eines zusätzlichen Funktionsaufrufs ist vernachlässigbar im Vergleich zu dem Overhead beim Eingeben und Verlassen der parallel -Region. Sie können OpenMP-Pragmas in func verwenden - sie funktionieren aufgrund des dynamischen Bereichs der parallel -Region.

Vielleicht würde Apple in Zukunft einen festen Compiler zur Verfügung stellen, mögen sie es nicht tun, wenn sie sich verpflichten, GCC durch Clang zu ersetzen.

    
Hristo Iliev 18.10.2012, 18:32
quelle

Tags und Links