Warum nimmt TCP / IP unter Windows7 500 Sends zum Aufwärmen? (w10, w8 erwies sich nicht zu leiden)

9

Wir sehen ein bizarres und unerklärliches Phänomen mit ZeroMQ auf Windows 7 , Senden von Nachrichten über TCP. (oder über inproc , wie ZeroMQ verwendet TCP intern zur Signalisierung, unter Windows).

Das Phänomen ist, dass die ersten 500 Nachrichten immer langsamer ankommen und die Latenz stetig steigt. Dann sinkt die Latenz, und Nachrichten kommen konsistent schnell an, mit Ausnahme von Spitzen, die durch CPU- / Netzwerkkonflikte verursacht werden.

Das Problem wird hier beschrieben: Ссылка

Es sind konsistent 500 Nachrichten. Wenn wir ohne Verzögerung senden, werden die Nachrichten in einem Stapel zusammengefasst, so dass wir sehen, dass sich das Phänomen über mehrere tausend Sends erstreckt. Wenn wir zwischen Sends verzögern, sehen wir den Graphen klarer. Selbst die Verzögerung von bis zu 50-100 ms zwischen Sends ändert nichts.

Die Nachrichtengröße ist ebenfalls irrelevant. Ich habe mit 10-Byte-Nachrichten und 10K-Nachrichten mit den gleichen Ergebnissen getestet.

Die maximale Latenz beträgt immer 2 ms (2.000 usec).

Auf Linux-Boxen sehen wir dieses Phänomen nicht.

Was wir gerne tun würden, ist diese Anfangskurve zu eliminieren, so dass Nachrichten mit ihrer normalen niedrigen Latenz (ca. 20-100 usec) auf einer neuen Verbindung bleiben.

  

Update: Das Problem tritt unter Windows 10 und Windows 8 nicht auf. Es scheint nur only unter Windows 7 zu passieren.

    
Pieter Hintjens 29.10.2015, 08:58
quelle

1 Antwort

2

Wir haben die Ursache und einen Workaround gefunden. Dies ist ein generelles Problem bei allen TCP-Aktivitäten unter Windows 7 (zumindest), die durch die Pufferung auf der Empfängerseite verursacht werden. Sie können einige Hinweise in der Zeile unter "TCP-langsamer Start" finden.

Bei einer neuen Verbindung oder wenn die Verbindung für 150 ms oder mehr inaktiv ist, puffert der Empfänger eingehende Pakete und stellt diese nicht der Anwendung zur Verfügung, bis der Empfangspuffer ist voll und / oder ein Timeout läuft ab (es ist unklar).

Unsere Problemumgehung in ZeroMQ, wo wir TCP-Sockets für Inter-Thread-Signalisierung verwenden, besteht darin, einen Dummy-Datenblock über neue Signalpaare zu senden. Dies zwingt den TCP-Stack dazu, "normal" zu arbeiten, und dann sehen wir konsistente Latenzen von etwa 100-150 usec.

Ich bin mir nicht sicher, ob das überhaupt nützlich ist; Für die meisten Anwendungen lohnt es sich, beim Empfang ein wenig zu warten, damit der TCP-Stack mehr an die aufrufende Anwendung liefern kann.

Allerdings kann diese Problemumgehung für Apps, die viele kleine Nachrichten senden, hilfreich sein.

Beachten Sie, dass, wenn die Verbindung im Leerlauf ist, der langsame Start erneut auftritt, so dass die Verbindungen alle 100 ms einen Heartbeat erhalten sollten, wenn dies kritisch ist.

    
Pieter Hintjens 30.10.2015 11:45
quelle