OpenMP: Große performance-Unterschiede zwischen Visual C++ 2008 und 2010
Bin ich mit einem Kamera-Akquisitions-Programm ausführt, die Verarbeitung auf die erworbenen Bilder, und ich bin mit einfache OpenMP-Direktiven für diese Verarbeitung. Also im Grunde warte ich auf ein Bild aus der Kamera, und dann verarbeiten.
Beim migrieren zu VC2010, sehe ich sehr seltsame performance hog : unter VC2010 meine app nimmt fast 100% CPU, während es nur 10% unter VC2008.
Wenn ich benchmark nur die Verarbeitung code bekomme ich keinen Unterschied zwischen VC2010 und VC2008, der Unterschied tritt auf, wenn mit der übernahme von Funktionen.
Habe ich reduziert den code, der benötigt wird um das problem zu reproduzieren, um eine einfache Schleife, die Folgendes macht:
for (int i=0; i<1000; ++i)
{
GetImage(buffer);//wait for image
Copy2Array(buffer, my_array);
long long sum = 0;//do some simple OpenMP parallel loop
#pragma omp parallel for reduction(+:sum)
for (int j=0; j<size; ++j)
sum += my_array[j];
}
Diese Schleife isst 5% der CPU mit 2008, und 70% mit 2010.
Ich habe einige profiling, das zeigt, dass im Jahr 2010 die meiste Zeit wird damit verbracht, in OpenMP ist vcomp100.dll!_vcomp::PartialBarrierN::Block
Habe ich auch einige gemacht Parallelität profiling:
2008, Bearbeitung verteilt sich auf 3 worker-threads, die sind sehr leicht aktiver als die Verarbeitungszeit ist viel schlechter als image Wartezeit
Den gleichen threads angezeigt, in 2010, aber Sie sind alle 100% belegt durch die PartialBarrierN::Block
Funktion. Als ich vier Kerne, die Sie Essen, 75% der Arbeit, das ist ungefähr das, was ich sehe in der CPU-Belastung.
So wie es aussieht gibt es einen Konflikt zwischen OpenMP und die Matrox Erwerb Bibliothek (proprietäre). Aber ist es ein Fehler von VS2010 oder Matrox?
Gibt es irgendetwas, was ich tun kann? Mit VC++2010 ist obligatorisch für mich, so kann ich nur mit Stock, 2008.
Großen Dank
STATUS-UPDATE
Über neue concurrency-framework, vorgeschlagen von DeadMG, führt zu 40% der CPU. Profiling zeigt es, dass die Zeit in der Verarbeitung, so dass es nicht in die bug ich bin zu sehen mit OpenMP, aber die Leistung in meinem Fall ist viel ärmer als OpenMP.
STATUS-UPDATE 2
Habe ich installiert eine Testversion der neuesten Intel C++. Es zeigt genau die gleichen performance-Probleme!!
Ich cross-gepostet MSDN-forum
STATUS-UPDATE 3
Getestet auf Windows 7 64 bit und XP 32 bits, mit der exakt gleichen Ergebnisse (auf der gleichen machinje)
- Es verbraucht 100% der CPU, aber wie lange dauert es? Läuft es schneller?
- Nein, es läuft nicht schneller. In beiden Fällen kann ich das Bild Bearbeiten, bevor eine neue kommt, also wenn die Verarbeitung läuft schneller, ich will nicht sehen, es in mein Programm. Mein problem ist eher die CPU-hog, als die Verarbeitungszeit.
- Mit OpenMP und nicht zu sehen, es verwenden alle Prozessor-Ressourcen ist das eigentliche problem. 100% Last ist das zu erwartende Ergebnis. Mehr hier: blogs.msdn.com/b/oldnewthing/archive/2010/12/03/10097861.aspx
- Sorry Hans, ich verstehe es nicht? Ich habe 100% geladen ist, während in der vorangegangenen situation weniger als 5% geladen. Also es ist übertrieben und abartig. In meinem richtigen Programm ich brauche die CPU zu tun, andere Verarbeitung, so dass es verlangsamt die Anwendung.
- Passant: diese Logik gilt nur für fixed-load-Programme. Dies ist ein fixed-rate-Programm: Sie erhalten eine Kamera-Bild alle 40 ms (typisch). Es gibt keine Möglichkeit, Sie können früher Schluss machen. Alle 40 ms die CPU-Nutzung sollte spike. Mit MP zu 100%, ja. Aber die Spitze sollte kürzer sein, und gemittelt über 40 ms das Ergebnis sollte etwa 5% betragen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
2010 OpenMP, jeder worker-thread ist ein spin-wait von etwa 200 ms nach Beendigung der Aufgabe. In meinem Fall ein I/O warten und sich wiederholende OpenMP Aufgabe es ist Massiv laden der CPU.
Die Lösung ist dieses Verhalten ändern; Intel C++ hat eine Erweiterung routine für diese
kmp_set_blocktime()
. Jedoch Visual 2010 nicht über eine solche Möglichkeit.In dieser Autodesk Hinweis Sie spricht über das problem für Intel C++. Dieser compiler eingeführt, die Verhalten, aber erlaubt zu ändern (siehe oben). Visual 2010 umgestellt, aber... ohne die Problemumgehung wie Intel.
Also, um es zusammenzufassen, der Wechsel zu Intel C++ und mit
kmp_set_blocktime(0)
gelöst.Dank an John Lilley aus DataLever Corporation auf die andere MSDN-thread
Frage vorgelegt worden MS-Connect, und erhielt die "won' T fix" - feedback.
Mit OpenMP 3.0 die spinwait können deaktiviert werden via
OMP_WAIT_POLICY
:Der Effekt ist im Grunde das gleiche wie mit
kmp_set_blocktime(0)
, aber wie setzen wir die UmgebungsvariableOMP_WAIT_POLICY
während der Laufzeit, es werden nur auf den aktuellen Prozess und Kindprozesse.Natürlich OMP_WAIT_POLICY kann auch eingestellt werden, indem ein launcher-Anwendung, z.B. Blender verarbeitet es so.
Einen hotfix für VC2010 verfügbar ist hier, spätere Versionen wie VC2013 support direkt.
Könnten Sie versuchen, die neuen Concurrency Runtime, die Schiffe mit VS2010 - nur ab auf Ihre Probe.
Ist,
werden würde
Getestet habe ich ein anderes Aufnahme-board, und das problem ist identisch, so dass die Täter VC++2010. Microsoft hat die OpenMP-Implementierung änderungen, die Schrauben up-Programme, wie mir, als thread auf MSDN-Foren zeigt.