Ich mache einige Benchmarks mit einem optimierten Java NIO Selektor auf Linux über Loopback (127.0.0.1).Java NIO Selektor minimal mögliche Latenz
Mein Test ist sehr einfach:
- Ein Programm sendet ein UDP-Paket an ein anderes Programm, das es zurück an den Absender und die Umlaufzeit berechnet wird Echo. Das nächste Paket wird nur gesendet, wenn das vorherige Paket bestätigt wurde (wenn es zurückkehrt). Ein richtiges Aufwärmen mit ein paar Millionen Nachrichten wird durchgeführt, bevor der Benchmark durchgeführt wird. Die Nachricht hat 13 Byte (ohne UDP-Header).
Für die Umlaufzeit ich die folgenden Ergebnisse erhalten:
- Min Zeit: 13 Mikros
- Avg Zeit: 19 Mikros
- 75% Perzentil: 18.567 Nanos
- 90% Perzentil: 18.789 Nanometer
- 99% Perzentil: 19.184 Nanometer
- 99,9% Perzentil: 19,264 Nanos
- 99,99% Perzentil: 19.310 Nanos
- 99,999% Perzentil: 19.322 Nanos
Aber der Haken dabei ist, dass ich Spinnen 1 Million Nachrichten.
Wenn ich nur 10 Nachrichten spinnen erhalte ich sehr unterschiedliche Ergebnisse:
- Min Zeit: 41 Mikros
- Avg Zeit: 160 Mikros
- 75% Perzentil: 150.701 nanos
- 90% Perzentil : 155.274 nanos
- 99% Perzentil: 159.995 nanos
- 99,9% Perzentil: 159.995 nanos
- 99,99% Perzentil: 159.995 nanos
- 99,999% Perzentil: 159.995 nanos
mich korrigieren, wenn ich falsch bin, aber ich vermute, dass, wenn wir den NIO-Selektor Spinnen die Reaktionszeiten werden optimal erhalten. Wenn wir jedoch Nachrichten mit einem ausreichend großen Intervall zwischen ihnen senden, zahlen wir den Preis für das Aufwecken des Selektors.
Wenn ich mit dem Senden nur einer einzigen Nachricht herumspiele, bekomme ich verschiedene Zeiten zwischen 150 und 250 Mikros.
Also meine Fragen für die Gemeinschaft sind:
1 - Ist meine Mindestzeit von 13 Mikros mit durchschnittlich 19 Mikros optimal für diese Rundfahrt Paket Test. Es sieht so aus, als würde ich ZeroMQ bei weitem schlagen, damit ich hier etwas vermisse.Von diesem Benchmark es wie ZeroMQ aussieht hat eine 49 Mikros avg Zeit (99% Perzentil) auf einem Standard-Kernel =>http://www.zeromq.org/results:rt-tests-v031
2 - Gibt es etwas, was ich tun kann die Wahlreaktionszeit zu verbessern, wenn ich ein einzelnen oder sehr spinnen einige Nachrichten? 150 Mikros sieht nicht gut aus. Oder sollte ich davon ausgehen, dass auf einer Prod-Umgebung der Selektor nicht ganz sein wird?
Durch beschäftigt drehen um selectNow() kann ich bessere Ergebnisse erzielen. Das Senden von wenigen Paketen ist immer noch schlimmer als das Senden vieler Pakete, aber ich denke, dass ich jetzt die Selektor-Leistungsgrenze erreiche. Meine Ergebnisse:
- Senden eines einzelnen Pakets bekomme ich eine konsistente 65 Mikro-Umlaufzeit.
- Mit zwei Paketen erreiche ich im Durchschnitt 39 Mikro-Round-Trip-Zeit.
- Mit 10 Paketen erreiche ich durchschnittlich 17 Mikro-Round-Trip-Zeit.
- Durch das Senden von 10.000 Paketen erreiche ich im Durchschnitt eine Umlaufzeit von 10.098 Nanosekunden.
- Senden 1 Million Pakete bekomme ich im Durchschnitt 9.977 Nanos Umlaufzeit.
Schlussfolgerungen
So sieht es aus wie die physische Barriere für die UDP-Paket Rundfahrt ist ein Durchschnitt von 10 Mikrosekunden, obwohl ich einige Pakete bekam die Reise in 8 Mikros (min Zeit) machen .
Mit viel Spinnerei (danke Peter) konnte ich im Durchschnitt von 200 Mikros auf durchschnittlich 65 Mikros für ein einzelnes Paket gehen.
Nicht sicher, warum ZeroMQ ist 5 times slower als das. (Edit: Vielleicht, weil ich mich entschieden diese auf derselben Maschine durch Loopback und ZeroMQ wird zwei verschiedene Maschinen verwenden?)
Ich denke, dass viel davon auf HotSpot JVM Aufwärmzeiten eher als das Verhalten von Selektoren spezifisch zurückzuführen ist. – EJP
Danke @EJP, aber ich habe mit dem JVM im Server-Modus etwas Warmup gemacht. Ich habe ein paar Millionen Nachrichten gesendet, bevor ich die Nachrichten gesendet habe, die den Benchmark auslösen werden. Warum denkst du das passiert? => "Wenn ich mit dem Senden einer einzigen Nachricht herumspiele, bekomme ich verschiedene Zeiten zwischen 150 und 250 Mikros." – Julie
rufen Sie mich verrückt, aber warum nicht einfach implementieren Sie Ihr (aus Beschreibung) Kurzprogramm in C und sehen Sie die Leistung. – NoSenseEtAl