Hallo,
wenn man größere Datenmengen beispielsweise 10 GB aufgeteilt in mehreren
Chunks von A nach B senden will, gibt es da eine empfehlenswerten
Chunkgrößenbereich auch im Hinblick auf übliche Netzwerkkarten und OS?
5MB, 10MB, 50MB, 100MB, 500MB... ?
Gefühlt würde ich irgendwas zwischen 5MB-50MB nehmen. Ich Frage mich
eben was ist im Hinblick auf die Übertragung besser, eher größere Chunks
oder kleinere oder ist es am Ende völlig egal?
Im Netz konnte ich dazu nichts konkretes finden nur das Leute nach der
maximalen Buffer Größe gefragt haben wo aber auch nicht beantwortet
wurde wo eigentlich das limit für den read buffer ist:
https://stackoverflow.com/questions/31999875/c-boostasio-whats-the-maximum-buffer-size-i-can-use-for-tcp-sockets
Mir geht es aber auch nicht darum die maximal möglichen Buffergrößen
auszunutzen sondern einen ungefähren allgemein guten Größenbereich für
Chunks zu definieren.
Involviert sind ja neben den Programmen auch Netzwerkkarte und OS daher
würde mich interessieren ob es in dieser Hinsicht aus der Praxis da
einen Größenbereich in MB gibt der zu empfehlen ist welcher mit
Netzwerkkarte und OS gut harmoniert? Wie groß würdet ihr persönlich
solche Chunks ungefähr machen?
Es geht um diese Funktionen:
https://www.boost.org/doc/libs/1_75_0/doc/html/boost_asio/reference/write/overload1.htmlhttps://www.boost.org/doc/libs/1_75_0/doc/html/boost_asio/reference/read/overload1.html
Grüße
Naja die 1500 Bytes beantworten nicht so richtig meine Frage. Das ist ja
low level mit dieser MTU habe ich ja durch die Nutzung von boost asio
nichts zu tun.
Asio wird ja vermutlich intern die Daten entsprechend dieser MTU
irgendwie selbst fragmentieren aber darum muss (und will) ich mich als
Anwender der Library nicht kümmern.
https://www.boost.org/doc/libs/1_75_0/doc/html/boost_asio.html
Meine Frage bezog sich auf selbst gewählte Chunkgrößen in MB Bereich als
Sende/Empfangs-buffer der boost asio Funktionen write() und read().
AsioPP schrieb:> Asio wird ja vermutlich intern die Daten entsprechend dieser MTU> irgendwie selbst fragmentieren aber darum muss (und will) ich mich als
asio macht da gar nichts. Der IP Stack ist normalerweise Bestandteil des
Betriebssystems. Das gesamte IP Protokoll wird darin bearbeitet. Im
Endeffekt wird es auch nur ein write() bzw send() auf dem Filehandle des
Sockets ausführen.
Das Ziel von asio ist es auch nicht eine besonders hohe Performance zu
erreichen sondern die Umsetzung von Event-Basierten
Softwarearchitekturen zu vereinfachen/vereinheitlichen. Im Wesentlichen
versteckt es das Verhalten der verschiedenen verfügbaren Socket APIs
hinter einer einheitlichen, eventbasierten Schnittstelle.
AsioPP schrieb:> Das> ist ja> low level mit dieser MTU habe ich ja durch die Nutzung von boost asio> nichts zu tun.
Deine Frage oben bezog sich ja nun ausdrücklich auf Netzwerkkarten.
Du planst also ein völlig eigenes Protokoll über Netzwerkkarten, für
zwei direkt per Kabel verbundenen Rechnern?
Ansonsten, wenn’s doch udp o.ä. ist, kannst du „high Level“ so große
Blöcke definieren, wie auch immer du willst. Der Netzwerkstack wird die
in MTU-große Blöcke aufteilen. Größer geht halt nicht.
Oliver
Ok ich versuche es nochmal, meine Frage ist: wenn man bei write()/send()
die Buffersize selbst definiert (weil man zb 10-20 GB Daten in Teilen
übertragen will) wie groß würdet ihr diese Buffer-/Chunksize wählen?
Beispiel A:
10 GB Daten mit Chunksize 10MB:
-> bedeutet 1000x write() aufrufen und jeweils 10MB Chunk senden.
Beispiel B:
10 GB Daten mit Chunksize 50MB:
-> bedeutet 200x write() aufrufen und jeweils 50MB Chunk senden.
Beispiel C:
10 GB Daten mit Chunksize 250MB:
-> bedeutet 40x write() aufrufen und jeweils 10MB Chunk senden.
Welche Chunksize in MB ist sinnvoll, welche nicht sinnvoll?
Wenn ihr euch zwischen A B C entscheiden müsstet, welches würdet ihr
wählen und warum?
Oliver S. schrieb:> Du planst also ein völlig eigenes Protokoll über Netzwerkkarten, für> zwei direkt per Kabel verbundenen Rechnern?
Nein ich will nur Große Datenmengen (zB 10-20 GB) als mehrere Häppchen
verschicken. Also mehrmaliger Aufruf von write() mit jeweils einem
Häppchen. Meine Frage ist wie groß würdet ihr die Häppchen machen in MB?
> Ansonsten, wenn’s doch udp o.ä. ist, kannst du „high Level“ so große> Blöcke definieren, wie auch immer du willst. Der Netzwerkstack wird die> in MTU-große Blöcke aufteilen. Größer geht halt nicht.
Es ist TCP/IP wie im Titel. Also Häppchengröße am Ende völlig egal? oder
gibt es nicht für größere oder kleinere Häppchen ein für oder wieder?
kommt doch darauf an wieviel Speicher man hat und wieviel man für einen
Buffer spendieren will.
Letztendlich wird write in einer Schleife aufgerufen und es meldet
zurück wieviel geschrieben wurde, bei TCP schon unabhängig von der MTU
size. Das zieht man von der gesamt Anzahl ab und setzt den Zeiger im
Sendebuffer um die Anzahl weiter. Solange bis alles weg ist.
Das passiert intern, da muss man sich dann nicht drum kümmern. Die
Chunks hat dann Asio eingeführt. Bekommt man ein Event wenn ein Chunk
gesendet wurde? Das macht Sinn wenn man einen neuen bereitstellen muss.
Johannes S. schrieb:> Bekommt man ein Event wenn ein Chunk> gesendet wurde? Das macht Sinn wenn man einen neuen bereitstellen muss.
ja also die Asio Funktion write() blockiert bis alles raus ist und dann
gehts weiter. genau umsetzung so bisschen wie schleife also daten
akkumulieren sich beim sender rein solange bis chunksize ausreicht und
dann wird verschickt an empfänger.
> kommt doch darauf an wieviel Speicher man hat und wieviel man für einen> Buffer spendieren will.
Ok also dann klingt es ja etwas wie als wäre es egal wieviel MB man pro
Chunk wählt und man guckt einfach das der RAM Verbrauch der Programme
nicht "zu hoch" wird.
von 'Chunks' steht da in der Doku ja nichts. Wenn du den Datenblock als
10 GB am Stück im RAM liegen hast, dann kann man den ja direkt als
Buffer nehmen. Wenn die Daten sowieso erstmal Häppchenweise gelesen
werden, dann reichen ein paar MB oder weniger als Buffer. Das die write
Funktion dann mehrmals aufgerufen wird, wird nicht messbar sein.
Beim write kann man mehrere Buffer angeben, aber das macht Sinn für
Scatter Gather IO, also z.B. wenn man Header und Nutzdaten bekommt, dann
lassen die sich mit einem Aufruf schon getrennt übertragen.
Und andere Überladungen erlauben schon eine completion_condition zu
übergeben, ein callback der aufgerufen wird wenn die Übertragung
komplett ist. Sonst würde 'Asio' auch keinen Sinn machen.
Damit sind kleine Blöcke sinnvoll, wenn z.B. die Daten von der Platte
geladen werden oder man einen Fortschritt aktualisieren will.
aber die magst du doch nicht, oder war es A.K.?
Die MTU spielt aber keine Rolle, bei TCP wird solange rausgefeuert wie
der Gegner eine window size >0 anbietet und seine ACKs schickt.
AsioPP schrieb:> Es ist TCP/IP wie im Titel. Also Häppchengröße am Ende völlig egal? oder> gibt es nicht für größere oder kleinere Häppchen ein für oder wieder?
Ganz egal nicht. Für jede Datei fällt ja auch noch ein nicht
unerheblicher Overhead im Filesystem. Auf der einen Datei die Datei
suchen und öffnen, auf der anderen diese erstmal anzulegen, den Inhalt
hinzuzufügen, das Filesystem aktualisieren usw.
Kopiere als Test einfach mal per SMB eine Große Datei und einmal die
gleiche Datenmenge in vielen Minidateien von einem Rechner auf einen
anderen.
Und die TCP-Paketgröße hat durchaus auch eine Bewandtnis. Damit bekommst
ja nicht immer jedes Packt voll und es kommt auf die genauen
Einstellungen deines OS und deiner NIC an ob da noch auf weitere Daten
gewartet wird oder das so gesendet wird. Und für jede Datei kommen
dazwischen ja auch noch Datenpackete für das Datei Handling. Insgesamt
bekommst du damit zu kleinen Dateien ganz schnell einen recht großen
Overhead und auch Latenzen rein.
Wobei deiner Konstellation genau der Punkt ist wo der durch jede Dateien
verursachte Overhead gegenüber der Zeit für die Datenübertragung nicht
mehr wirklich ins Gewicht fällt musst du Ausprobieren...
Im Extrem mit noch kleineren Dateien. Ich hatte es schon gehabe das es
sinnvoller war über 1Mio. Dateien mit 1-5KB erst zu einer Datei zu
packen, diese eine Datei dann zu übertragen und im Ziel wieder
Auszupacken. Das war einige Stunden schnelle als jede Datei einzeln zu
übertragen.
Johannes S. schrieb:> von 'Chunks' steht da in der Doku ja nichts.
mit "chunks" meinte ich nur die häppchen des ganzen.
> Das die write> Funktion dann mehrmals aufgerufen wird, wird nicht messbar sein.
Ok das ist gut zu wissen!
Dann ist es ja im Bezug auf OS/Netzwerkkarte/usw tatsächlich wohl echt
völlig egal ob ich Daten in Asio an einem Stück oder aufgeteilt in
mehreren Teilen verschicke. Kann man dann je nach Anwendungsfall
entscheiden. Fazit für mich dann jetzt: 10GB Daten via Asio in 5MB
Chunks oder komplett in einem Rutsch ist also am Ende völlig egal :-)
AsioPP schrieb:> Fazit für mich dann jetzt: 10GB Daten via Asio in 5MB> Chunks oder komplett in einem Rutsch ist also am Ende völlig egal :-)
mach doch einfach einen Test und stoppe die Zeit in beiden Fällen, da
sind ja nur ein paar Zahlen zu ändern.
Anders ist es bei vielen ganz kleinen Päckchen, wenn du dem Gegner immer
nur ein paar Byte schicken willst, dann sammelt der Sender die Daten
üblicherweise und sendet die verzögert (Nagle Algorithmus). Und wenn man
das abschaltet kann der Gegner immer noch sagen 'das sind mir zuviele
kleine Störungen' und schickt sein Ack verzögert. Also relativ große
Brocken (zig kb) mögen die Rechner heute lieber.
Irgend W. schrieb:> Für jede Datei fällt ja auch noch ein nicht> unerheblicher Overhead im Filesystem.
Mir ging es bei der Frage in erster Linie um die reine Übertragung von
Programm zu Programm mit dem laden/schreiben auf Platte kam erst als
Beispiel durch Johannes. Der Aspekt mit den Dateien ist aber interessant
für Anwendungsfälle wo die Speicherung und so eine Rolle spielt, danke
für den Hinweis werde das im Hinterkopf behalten vor diesem Hintergrund
da die "Chunks" eher groß zu halten.
Johannes S. schrieb:> mach doch einfach einen Test und stoppe die Zeit in beiden Fällen, da> sind ja nur ein paar Zahlen zu ändern.
ja richtig, Zeit stoppen macht da am meisten Sinn
> Also relativ große> Brocken (zig kb) mögen die Rechner heute lieber.
ok super dann weiß ich bescheid danke für die Infos
> 10GB Daten via Asio in 5MB Chunks oder komplett in einem Rutsch ist> also am Ende völlig egal
Asio brauchst du nicht (das korrekt hinzubekommen ist nen ziemliches
Gewürge). Die Daten, die eh im Speicher sind, kannst du in einem Stück
raushauen. Wenn du abwechselt von Platte liest, auf Netz schreibst,
würd ich eher bei kleineren Größen (4-128kB) bleiben - dann kann das
Betriebssystem das durch prefetch/buffer ganz gut parallelisieren, ohne
dass du Hand anlegen musst.