2009-04-22 5 views
1

Ich teste meine Java-Anwendung für etwaige Leistungsengpässe. Die Anwendung verwendet concurrent.jar zum Sperren.Java Performance Degradation beim Entfernen von Sperren

Ich habe einen hohen Berechnungsanruf, der für seine Operationen Sperr- und Entsperrfunktionen aufruft. Beim Entfernen des Lock-Unlock-Mechanismus aus dem Code habe ich die Leistungseinbußen durch Mehrfachfalten gesehen, was meinen Erwartungen widerspricht. Unter anderem wurde beobachtet, dass der CPU-Verbrauch anstieg, was mir das Gefühl gab, dass das Programm schneller läuft, aber eigentlich nicht.

Q1. Was kann der Grund für diese Leistungseinbußen sein, wenn wir Sperren entfernen?

Beste Grüße !!!

Antwort

3

Dies kann ein ganz normaler Befund sein, abhängig davon, was Sie gerade tun und was Sie als Alternative zu Locks verwenden.

Im Wesentlichen, was passiert, ist, dass Konstrukte wie ReentrantLock eine gewisse Logik eingebaut haben, die weiß, wann sie sich zurückziehen müssen, wenn sie das Schloss realistischerweise nicht erfassen können. Dies reduziert die CPU-Menge, die gerade in der Logik des wiederholten Zugriffs auf die Sperre verbraucht wird. Dies kann passieren, wenn Sie einfachere Sperrkonstrukte verwenden.

Als Beispiel, werfen Sie einen Blick auf die Grafik, die ich eilig here gestellt habe. Es zeigt den Durchsatz von Threads, die kontinuierlich auf zufällige Elemente eines Arrays zugreifen, wobei verschiedene Konstrukte als Sperrmechanismus verwendet werden. Entlang der X-Achse ist die Anzahl der Threads; Y-Achse ist der Durchsatz. Die blaue Linie ist ein ReentrantLock; die gelben, grünen und braunen Linien verwenden Varianten eines Spinlocks. Beachten Sie, dass der Spinlock bei geringer Anzahl von Threads einen höheren Durchsatz bietet, wie Sie vielleicht erwarten würden, aber wenn die Anzahl der Threads steigt, wird die Back-Off-Logik von ReentrantLock aktiviert und es geht besser, während bei hohen Constraints die Spinlocks sitzen nur brennende CPU.

Übrigens war dies wirklich ein Testlauf auf einem Dual-Prozessor-Maschine; Ich habe es auch in der Amazon Cloud (effektiv ein 8-Wege Xeon) ausgeführt, aber ich habe ahem ... die Datei verlegt, aber ich werde es entweder finden oder das Experiment bald wieder ausführen und ein Update trainieren und posten. Aber Sie erhalten ein im Wesentlichen ähnliches Muster, wie ich mich erinnere.

Update: ob es in Code Sperren oder nicht, ein Phänomen, das auf einigen Multi-Prozessor-Architekturen passieren kann, ist, dass, da die mehrere Prozessoren ein hohes Volumen an Speicher tun zugreift, können Sie den Speicher-Bus am Ende überschwemmen, und in bewirken, dass sich die Prozessoren gegenseitig verlangsamen.(Es ist ein bisschen wie mit Ethernet - je mehr Maschinen Sie dem Netzwerk hinzufügen, desto größer ist die Wahrscheinlichkeit von Kollisionen, wenn Daten gesendet werden.)

+0

Das ist ein schöner Fund. Aber was ist mit dem Entfernen der Schlösser insgesamt? Soll das die Performance nicht verbessern ?? – pankajt

+0

Es hängt davon ab - wenn Sperren erforderlich war, damit das Programm korrekt funktioniert und Sie es nur willkürlich entfernt haben, was ist dann Ihre Messung der "Leistung" und wie gültig ist sie? Es ist schwer zu sagen, ohne mehr darüber zu wissen, was Sie tun und die Architektur, auf der Sie laufen ... –

+1

Siehe auch mein Update über Speicherbus-Flooding: Wenn mehrere Prozessoren Speicher mit einer hohen Anzahl von Schreibvorgängen hämmern, dann können sie können sich gegenseitig negativ beeinflussen. Ich sage nicht, dass dies notwendigerweise ist, was passiert - aber es ist ein Beispiel dafür, wie die Dinge ziemlich komplex sind, und Sie erwarten nicht unbedingt "Sperren entfernen", um die Leistung magisch zu steigern ... –

3

Profil es. Alles andere hier wird nur eine Vermutung und eine uninformierte sein.

ein Profiler wie YourKit Verwendung finden Sie nicht nur sagen, welche Methoden „hot spots“ in Bezug auf die CPU-Zeit, aber es wird Ihnen auch sagen, wo Themen die meiste Zeit verbringen GESPERRT oder

+0

Ich muss der Antwort hier widersprechen Kevin. Ich habe meinen Code bereits profiliert und leiht mich nirgends. Um die Dinge zu vereinfachen, ist der Code, den ich auf dem CPUS (8-CPU-Box) ausgeführt habe, ein CPU-intensiver Prozess. Die Brennpunkte in Bezug auf die CPU-Zeit sind genau die gleichen für 1. Der Code mit Sperren und 2. der Code ohne Sperren. Offensichtlich fehlen die Sperrenaufrufe in der Sekunde, aber wenn ich sage, dass es ein CPU-intensiver Prozess ist, sollte die Leistung von Code 2 ohne Sperre mehr gewesen sein. Haben Sie andere Ideen? Danke Kevin für Antworten – pankajt

1

WAITING Ist es noch richtig funktionieren? Zum Beispiel gab es einen Fall in einem App-Server, wo eine unsynchronisierte HashMap eine gelegentliche Endlosschleife verursachte. Es ist nicht schwer zu sehen, wie die Arbeit einfach wiederholt werden kann.

+0

Ich habe versucht, die Leistung der Anwendung mit und ohne Sperren zu vergleichen. Natürlich, wenn Sperren entfernt wurden, habe ich "gleichzeitige Änderung Ausnahme" in einigen Threads ausgeführt. – pankajt

+0

Nicht jeder Fehler wird erkannt. Sie vergleichen nicht mit Gleichem. –

0

Die wahrscheinlichste Ursache dafür, dass die Leistung abnimmt und die CPU-Auslastung steigt, wenn Sie den Schutz für gemeinsam genutzte Speicher entfernen, ist eine Race-Bedingung. Zwei oder mehr Threads könnten kontinuierlich ein Zustandsflag auf einem gemeinsamen Objekt hin und her spiegeln.

Weitere Beschreibung des Zwecks Ihrer Anwendung würde bei der Diagnose helfen.

Verwandte Themen