Frage

Ich schreibe ein Feed -Forward -Netz in VC ++ unter Verwendung von AVX -Intrinsics. Ich berufe diesen Code über Pinvoke in C#. Meine Leistung beim Aufrufen einer Funktion, die eine große Schleife einschließlich der Funktion exp () berechnet, beträgt ~ 1000 ms für eine Loopse von 160 m. Sobald ich rufe irgendein Funktion, die AVX -Intrinsik verwendet und anschließend exp () verwendet, fällt meine Leistung für denselben Betrieb auf ca. ~ 8000 ms. Beachten Sie, dass die Funktion des Exp () Standard C ist, und der Aufruf, der die AVX -Intrinsics verwendet, kann in Bezug auf die verarbeiteten Daten völlig nichts in Verbindung gebracht werden. Eine Art Flagge wird zur Laufzeit irgendwo gestolpert.

Mit anderen Worten,

A(); // 1000ms calculates 160M exp() 
B(); // completely unrelated but contains AVX
A(); // 8000ms

oder neugierig,

C(); // contains 128 bit SSE SIMD expressions
A(); // 1000ms

Ich bin verloren, welcher mögliche Mechanismus hier vor sich geht oder wie man ein Sol'n verfolgt. Ich bin auf einem Intel 2500K CPU Win 7. Expressversionen von Vs.

Vielen Dank.

War es hilfreich?

Lösung

Wenn Sie eine AVX256-Anweisung verwenden, wird der "AVX Upper State" "schmutzig", was zu einem großen Stand führt, wenn Sie anschließend SSE-Anweisungen verwenden (einschließlich Skalar-Schwimmpunkte, die in den XMM-Registern durchgeführt werden). Dies ist im Intel -Optimierungshandbuch dokumentiert, das Sie können kostenlos herunterladen (Und ist ein Muss, wenn Sie diese Art von Arbeit machen):

Die AVX -Anweisung verändert immer die oberen Teile von YMM -Registern und SSE -Anweisungen ändern die oberen Bits nicht. Aus Hardware -Sicht können die oberen Teile der YMM -Registersammlung als in einem von drei Zuständen angesehen werden:

• Sauber: Alle oberen Teile von YMM sind Null. Dies ist der Zustand, in dem der Prozessor beim Zurücksetzen beginnt.

• Modifiziert und in XSAVE -Region gespeichert Der Inhalt der oberen Bits von YMM -Registern entspricht gespeicherte Daten im XSAVE -Bereich. Dies geschieht, wenn nach xsave/xrstor ausgeführt wird.

• Modifiziert und nicht gerettet: Die Ausführung einer AVX-Anweisung (entweder 256-Bit oder 128-Bit) verändert die oberen Bits des Ziels ymm.

Die AVX/SSE -Übergangsstrafe gilt, wenn der Prozessorstaaten „modifiziert und nicht gerettet“ ist. Verwenden von Vzeroupper Bewegen Sie die Prozessorzustände, um „zu reinigen“ und die Übergangsstrafe zu vermeiden.

Ihre Routine B( ) Dirties der YMM -Zustand, also der SSE -Code in A( ) Stände. Einfügen a VZEROUPPER Anweisung zwischen B und A um das Problem zu vermeiden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top