Discussion:
Performance read() vs. sendfile() vs. mmap() @ Socket AF_UNIX
(zu alt für eine Antwort)
Ulf Wendel
2003-10-25 15:24:25 UTC
Permalink
Ahoi,

ich bin gerade etwas verwirrt von der Performance, die meine zwei
kleinen Programme Server und Client messen, wenn sie miteinander reden.
Server und Client kommunizieren über ein Unix Domain Socket miteinander.
Der Client sendet dem Server Dateinamen, die dieser entgegennimmt und
als Antwort den Inhalt der Datei schickt. Das Auslesen der Dateien und
das Senden über das Socket erfolgt mittels drei Varianten: read(),
sendfile(), mmap().

Ich erhalte folgende Laufzeiten für einen Testlauf mit 10.000 Dateien
aus /usr/src/linux:

sendfile()-Variante:
Gesamt: 4.28s
User: 0.08s
System: 1.11s

read()-Variante:
Gesamt: 5.51s
User: 0.17s
System: 1.17s

mmap()-Variante:
Gesamt: 18.57s
User: 0.18s
System: 11.49s

Die Zeiten werden im Server gemessen. Wie ist das Abschneiden von mmap()
zu erklären?

Ein Stückchen mmap() Implementierung habe ich unten angehängt. Der Code
vor und nach dem [...] ist in allen Varianten des Servers identisch.

Danke!

Ulf



[...]

if ((fd = open(filename, O_RDONLY)) == -1) {
snprintf(buffer, BUFFER_SIZE,
"SERVER: failed to open '%s'", filename);
write(con_fd, buffer, strlen(buffer));
return -1;
}

map_ptr = mmap(NULL, stat_info.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (map_ptr == ((caddr_t)-1)) {
snprintf(buffer, BUFFER_SIZE,
"SERVER: mmap() failure on file '%s'", filename);
write(con_fd, buffer, strlen(buffer));
return -1;
}
close(fd);

if (write(con_fd, map_ptr, stat_info.st_size) != stat_info.st_size) {
snprintf(buffer, BUFFER_SIZE,
"SERVER: failed to write %d Bytes to socket", n);
write(con_fd, buffer, strlen(buffer));
return -1;
}

if (munmap(map_ptr, stat_info.st_size) == -1)
log_and_exit("munmap failed");

[...]
Matthias Trute
2003-10-25 15:34:47 UTC
Permalink
Post by Ulf Wendel
Ahoi,
ich bin gerade etwas verwirrt von der Performance, die meine zwei
kleinen Programme Server und Client messen, wenn sie miteinander reden.
Server und Client kommunizieren über ein Unix Domain Socket miteinander.
Der Client sendet dem Server Dateinamen, die dieser entgegennimmt und
als Antwort den Inhalt der Datei schickt. Das Auslesen der Dateien und
das Senden über das Socket erfolgt mittels drei Varianten: read(),
sendfile(), mmap().
Folgendes könnte weiterhelfen:

http://bulk.fefe.de/scalability/

Inkl. Source zum selbertesten.

Matthias
Ulf Wendel
2003-10-25 19:07:01 UTC
Permalink
Post by Matthias Trute
Post by Ulf Wendel
Ahoi,
ich bin gerade etwas verwirrt von der Performance, die meine zwei
kleinen Programme Server und Client messen, wenn sie miteinander reden.
Server und Client kommunizieren über ein Unix Domain Socket miteinander.
Der Client sendet dem Server Dateinamen, die dieser entgegennimmt und
als Antwort den Inhalt der Datei schickt. Das Auslesen der Dateien und
das Senden über das Socket erfolgt mittels drei Varianten: read(),
sendfile(), mmap().
http://bulk.fefe.de/scalability/
Uff,

um alles zu lesen, bin ich inzwischen zu müde. Das enthält also eine
Erklärung, warum mmap() so dramatisch einbricht?

Danke!

Ulf
Ulf Wendel
2003-10-26 15:07:12 UTC
Permalink
Post by Matthias Trute
http://bulk.fefe.de/scalability/
Ich habe es inzwischen gelesen. Danke für den Tipp, ich kann die URL gut
verwenden.

Ulf
Rainer Weikusat
2003-10-26 11:10:34 UTC
Permalink
Post by Ulf Wendel
Ich erhalte folgende Laufzeiten für einen Testlauf mit 10.000 Dateien
Gesamt: 4.28s
User: 0.08s
System: 1.11s
Gesamt: 5.51s
User: 0.17s
System: 1.17s
Gesamt: 18.57s
User: 0.18s
System: 11.49s
Die Zeiten werden im Server gemessen. Wie ist das Abschneiden von
mmap() zu erklären?
Durch den vollständigen Code. Wie beim letzen Mal.
Ulf Wendel
2003-10-26 12:46:49 UTC
Permalink
Post by Rainer Weikusat
Post by Ulf Wendel
Die Zeiten werden im Server gemessen. Wie ist das Abschneiden von
mmap() zu erklären?
Durch den vollständigen Code. Wie beim letzen Mal.
Gerne,

reiche ich den Quellcode nach. Zum Quellcode muß ich sagen: jeder fängt
mal an. Belehrungen nehme ich gerne entgegen.

Der gesamte Quellcode mitsamt Testbeschreibung ist unter folgender URL
abrufbar:

http://www.ulf-wendel.de/stuff/client_server.html

Die Unterschiede in den Varianten des Servers liegen in der
Implementierung der Funktion server[x.c]:answer().

Freue mich auf die Tipps,

Ulf
Florian Weimer
2003-10-26 13:14:45 UTC
Permalink
Post by Ulf Wendel
Freue mich auf die Tipps,
Die Dateien sind zu klein. mmap() ist verdammt teuer. bis zu einer
gewissen Größe ist also kopieren billiger.
Rainer Weikusat
2003-10-26 13:38:13 UTC
Permalink
Post by Florian Weimer
Post by Ulf Wendel
Freue mich auf die Tipps,
Die Dateien sind zu klein. mmap() ist verdammt teuer. bis zu einer
gewissen Größe ist also kopieren billiger.
In dieser Form ist das nicht kompilierbar, insofern offensichtlich
nicht der Code, der für die Messung benutzt wurde, falls eine
durchgeführt wurde. Weitere Aussagen kann man darüber nicht machen.
Ulf Wendel
2003-10-26 14:57:24 UTC
Permalink
Post by Rainer Weikusat
Post by Florian Weimer
Post by Ulf Wendel
Freue mich auf die Tipps,
Die Dateien sind zu klein. mmap() ist verdammt teuer. bis zu einer
gewissen Größe ist also kopieren billiger.
In dieser Form ist das nicht kompilierbar, insofern offensichtlich
nicht der Code, der für die Messung benutzt wurde, falls eine
durchgeführt wurde. Weitere Aussagen kann man darüber nicht machen.
Du meinst Dir fehlen ein paar Dateien client.c/log_error.c/log_error.h.
Ich habe sie dem Dokument hinzugefügt:

http://ulf-wendel.de/stuff/client_server.html#code

Wenn kein grober Unfug im Quellcode gemessen wird, weil der Quellcode
falsch ist, genügt mir die Faustregel von Florian.

Das beantwortet meine Frage vollkommen. Warum diese Faustregel gelten
könnte, lese ich gerne selbst nach.

Ulf
Rainer Weikusat
2003-10-26 16:16:00 UTC
Permalink
Post by Ulf Wendel
Du meinst Dir fehlen ein paar Dateien
client.c/log_error.c/log_error.h.
Nein. Ich meine das hier (markierte Zeile):

map_ptr = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (map_ptr == ((caddr_t)-1)) {
snprintf(buffer, BUFFER_SIZE, "SERVER: mmap() failure on file '%s'", filename);
write(con_fd, buffer, strlen(buffer));
return -1;
}
close(fd);

if (write(con_fd, map_ptr, stat_info.st_size) != stat_info.st_size) {
snprintf(buffer, BUFFER_SIZE, "SERVER: failed to write %d Bytes to socket", n);
write(con_fd, buffer, strlen(buffer));
return -1;
}

munmap(map_ptr);
^^^^^^^^^^^^^^^

Das kriegst Du so nicht durch den Compiler, falls Du sys/mman.h
einbindest, denn der Prototyp sieht so aus:

/* Deallocate any mapping for the region starting at ADDR and extending LEN
bytes. Returns 0 if successful, -1 for errors (and sets errno). */
extern int munmap (void *__addr, size_t __len) __THROW;
[Linux, SUS ist bis auf die Namen identisch].

[***@winter]:/tmp $gcc -o /dev/null -c mmap.c
mmap.c: In function `answer':
mmap.c:137: too few arguments to function `munmap'

Falls Du einen Compiler haben solltest, der das ignoriert (möglich),
dann erklärt aus auch die gemessene Systemzeit: Du mappst der Reihe
nach 10.000 files in Deinem Adreßraum und unmappst zufällige Bereiche
von denen => paging.
Ulf Wendel
2003-10-26 17:41:23 UTC
Permalink
Post by Rainer Weikusat
munmap(map_ptr);
^^^^^^^^^^^^^^^
Das kriegst Du so nicht durch den Compiler, falls Du sys/mman.h
/* Deallocate any mapping for the region starting at ADDR and extending LEN
bytes. Returns 0 if successful, -1 for errors (and sets errno). */
extern int munmap (void *__addr, size_t __len) __THROW;
[Linux, SUS ist bis auf die Namen identisch].
mmap.c:137: too few arguments to function `munmap'
*autsch*, *duck*

Was soll ich sagen: den Umgang mit einem Compiler erlernen, gehört halt
auch zu den Dingen die, ein Anfänger erst lernen muß. Zu meiner
Entschuldigung kann ich nur anführen, daß der Compiler nicht gemeckert hat.

Und ja, danach ist die Performance eine ganz andere :-).

Ulf
Bastian Blank
2003-10-27 14:10:56 UTC
Permalink
Post by Ulf Wendel
Was soll ich sagen: den Umgang mit einem Compiler erlernen, gehört halt
auch zu den Dingen die, ein Anfänger erst lernen muß. Zu meiner
Entschuldigung kann ich nur anführen, daß der Compiler nicht gemeckert hat.
Lass mich raten, du benutzt gcc ohne -Wall -W? Dann verhält er sich
halt wie ein C-Compiler und baut sich die nicht vorhandenen Prototypen
selbst. Gerade als Anfänger sollte man es sich angewöhnen, immer -Wall
-W und sogar noch -Werror zu benutzen, was einem die üblichsten Fehler
anmerkt.

Bastian
Rainer Weikusat
2003-10-27 16:52:28 UTC
Permalink
Post by Bastian Blank
Post by Ulf Wendel
Was soll ich sagen: den Umgang mit einem Compiler erlernen, gehört halt
auch zu den Dingen die, ein Anfänger erst lernen muß. Zu meiner
Entschuldigung kann ich nur anführen, daß der Compiler nicht gemeckert hat.
Lass mich raten, du benutzt gcc ohne -Wall -W? Dann verhält er sich
halt wie ein C-Compiler und baut sich die nicht vorhandenen Prototypen
selbst.
Daran kann das nicht gelegen haben.
Post by Bastian Blank
Gerade als Anfänger sollte man es sich angewöhnen, immer -Wall
-W und sogar noch -Werror zu benutzen, was einem die üblichsten Fehler
anmerkt.
Gerade in neueren gcc-Versionen wird -Werror eine Menge Fehler
verursachen, die nicht mit Fehlern im Quelltext korrespondieren.
Florian Weimer
2003-10-27 21:04:12 UTC
Permalink
Post by Rainer Weikusat
Gerade in neueren gcc-Versionen wird -Werror eine Menge Fehler
verursachen, die nicht mit Fehlern im Quelltext korrespondieren.
Das haben Warnungen so an sich, sonst müßten es keine Warnungen sein.

Das Problem sind eher die Helden, die rekursives make und -Werror
einsetzen, ohne eine Möglichkeit, letzteres abzustellen. Wenn man ein
solches Projekt mit einer neueren GCC-Version zu übersetzen versucht,
ist das ein Heidenspaß (und nicht immer läßt sich das mit "perl -i..."
korrigieren).
Bastian Blank
2003-10-28 08:13:16 UTC
Permalink
Post by Florian Weimer
Das Problem sind eher die Helden, die rekursives make und -Werror
einsetzen, ohne eine Möglichkeit,
Wurde der Verursacher wenigstens gegrillt?

Bastian
Florian Weimer
2003-10-28 20:57:12 UTC
Permalink
Post by Bastian Blank
Post by Florian Weimer
Das Problem sind eher die Helden, die rekursives make und -Werror
einsetzen, ohne eine Möglichkeit,
Wurde der Verursacher wenigstens gegrillt?
Nein, das Projekt war schon im wesentlichen tot. Den Code wollte ich
mir lieber auch nicht genauer anschauen -- DCE/DCOM für Linux, da darf
man bestimmt gleich ein Advisory schreiben.

Rainer Weikusat
2003-10-28 11:36:46 UTC
Permalink
Post by Florian Weimer
Post by Rainer Weikusat
Gerade in neueren gcc-Versionen wird -Werror eine Menge Fehler
verursachen, die nicht mit Fehlern im Quelltext korrespondieren.
Das haben Warnungen so an sich, sonst müßten es keine Warnungen sein.
Und deswegen sollten es auch Warnungen bleiben, dh bis zum Beweis des
Gegenteils ernstzunehmende Hinweise.
Post by Florian Weimer
Das Problem sind eher die Helden, die rekursives make und -Werror
einsetzen, ohne eine Möglichkeit, letzteres abzustellen. Wenn man ein
solches Projekt mit einer neueren GCC-Version zu übersetzen versucht,
ist das ein Heidenspaß (und nicht immer läßt sich das mit "perl -i..."
korrigieren).
Warum denn immer perl?

find . -name Makefile | while read m;
do
ed $m <<TT
g/-Werror[^-a-z]/s/-Werror/
w
q
TT
done
Bastian Blank
2003-10-28 07:50:17 UTC
Permalink
Post by Rainer Weikusat
Post by Bastian Blank
Post by Ulf Wendel
auch zu den Dingen die, ein Anfänger erst lernen muß. Zu meiner
Entschuldigung kann ich nur anführen, daß der Compiler nicht gemeckert hat.
Lass mich raten, du benutzt gcc ohne -Wall -W? Dann verhält er sich
halt wie ein C-Compiler und baut sich die nicht vorhandenen Prototypen
selbst.
Daran kann das nicht gelegen haben.
Dann hätte er gemeckert, das er den Prototype nicht kennt.
Post by Rainer Weikusat
Gerade in neueren gcc-Versionen wird -Werror eine Menge Fehler
verursachen, die nicht mit Fehlern im Quelltext korrespondieren.
-Werror sagt erst mal nur aus, das alle Warnungen als Fehler gewertet
werden. Auch hat jede, solange du nicht Warnungen jenseits dieser Stufe
(z.b. -Wconversion) aktivierst, hat noch jede einen realen Hintergrund
(zumindest ist mir noch nie was anderes unter gekommen).

Bastian
Rainer Weikusat
2003-10-28 11:27:37 UTC
Permalink
Post by Bastian Blank
Post by Rainer Weikusat
Post by Bastian Blank
Post by Ulf Wendel
auch zu den Dingen die, ein Anfänger erst lernen muß. Zu meiner
Entschuldigung kann ich nur anführen, daß der Compiler nicht gemeckert hat.
Lass mich raten, du benutzt gcc ohne -Wall -W? Dann verhält er sich
halt wie ein C-Compiler und baut sich die nicht vorhandenen Prototypen
selbst.
Daran kann das nicht gelegen haben.
Dann hätte er gemeckert, das er den Prototype nicht kennt.
Falls der Ablauf so stattgefunden hat, wie der OP ihn beschrieben hat,
einschließlich des veröffentlichten Quelltextes, dann war der Prototyp
aber bekannt.
Post by Bastian Blank
Post by Rainer Weikusat
Gerade in neueren gcc-Versionen wird -Werror eine Menge Fehler
verursachen, die nicht mit Fehlern im Quelltext korrespondieren.
-Werror sagt erst mal nur aus, das alle Warnungen als Fehler gewertet
werden. Auch hat jede, solange du nicht Warnungen jenseits dieser Stufe
(z.b. -Wconversion) aktivierst, hat noch jede einen realen
Hintergrund
Das möchte man aber tun (-W und -Wall) um 'comparison between signed
and unsigned', mit dem man übel auf die Nase fallen kann, zu bekommen
und einige andere nützliche Meldungen, für die sämtlich gilt, daß sie
meistens ein Fehlalarm sind, aber nicht immer (und dann schwer zu
finden). Allerdings bekommt man dann für jeden longjmp gnadenlos eine
Warnung, egal ob man lokale Variablen 'volatile' oder sonstwie
deklariert. Das könnte natürlich ein verdeckter Hinweis sein, daß
'volatile' in gcc broken ist ...
Ulf Wendel
2003-10-26 13:46:27 UTC
Permalink
Post by Florian Weimer
Post by Ulf Wendel
Freue mich auf die Tipps,
Die Dateien sind zu klein. mmap() ist verdammt teuer. bis zu einer
gewissen Größe ist also kopieren billiger.
Ah,

das ist etwas, was mir eine große Datei sofort bestätigt. Danke!

Ulf
Rainer Weikusat
2003-10-26 13:20:36 UTC
Permalink
Post by Ulf Wendel
Post by Rainer Weikusat
Post by Ulf Wendel
Die Zeiten werden im Server gemessen. Wie ist das Abschneiden von
mmap() zu erklären?
Durch den vollständigen Code. Wie beim letzen Mal.
Gerne,
Der gesamte Quellcode mitsamt Testbeschreibung ist unter folgender URL
http://www.ulf-wendel.de/stuff/client_server.html
Da finde ich folgendes:

***@linux:~/code/server> ls -la client_*.log
-rw-r--r-- 1 ulf users 289858000 Okt 26 13:05 client_mmap.log
-rw-r--r-- 1 ulf users 289809009 Okt 26 13:03 client_sendfile.log
-rw-r--r-- 1 ulf users 289801100 Okt 26 13:02 client_write.log

dh jedes Deiner Programme übertragt 2898000 + X octets, und X variiert
von 1100 (read) bis 58000 (mmap). Letzteres ist ca 52 mal soviel, wie
ersteres. Angesichts dieser Tatsache ist es doch eigentlich ganz
ordentlich, daß der mmap-Code dafür nur rund 1.4 mal mehr Zeit
braucht.

Finde Dich bitte einfach damit ab, daß Du außerstande bist, daß
Interface vernünftig zu benutzen.
Ulf Wendel
2003-10-26 13:53:28 UTC
Permalink
Post by Rainer Weikusat
Post by Ulf Wendel
Post by Rainer Weikusat
Post by Ulf Wendel
Die Zeiten werden im Server gemessen. Wie ist das Abschneiden von
mmap() zu erklären?
Durch den vollständigen Code. Wie beim letzen Mal.
Gerne,
Der gesamte Quellcode mitsamt Testbeschreibung ist unter folgender URL
http://www.ulf-wendel.de/stuff/client_server.html
-rw-r--r-- 1 ulf users 289858000 Okt 26 13:05 client_mmap.log
-rw-r--r-- 1 ulf users 289809009 Okt 26 13:03 client_sendfile.log
-rw-r--r-- 1 ulf users 289801100 Okt 26 13:02 client_write.log
dh jedes Deiner Programme übertragt 2898000 + X octets, und X variiert
von 1100 (read) bis 58000 (mmap). Letzteres ist ca 52 mal soviel, wie
ersteres. Angesichts dieser Tatsache ist es doch eigentlich ganz
ordentlich, daß der mmap-Code dafür nur rund 1.4 mal mehr Zeit
braucht.
Ich verstehe nicht. Den Hinweis von Florian Weimer zur Dateigröße konnte
ich nachvollziehen (durch ausprobieren...), aber hier überforderst Du mich.

Bei bummelig 289 Millionen octets ist eine Differenz von 56.900 octets
nicht vernachlässigbar? Ohne zu verstehen was die Zahlen bedeuten, ist
schwer nachvollziehbar, daß ein Unterschied von 2 Promille zum Faktor
1.4 führt.
Post by Rainer Weikusat
Finde Dich bitte einfach damit ab, daß Du außerstande bist, daß
Interface vernünftig zu benutzen.
Dir ist klar, daß solch ein Satz nur eine Rückfrage provizieren kann ;-).

Wie benutze ich es "richtig"?

Danke!

Ulf
Rainer Weikusat
2003-10-26 14:11:52 UTC
Permalink
Post by Ulf Wendel
Bei bummelig 289 Millionen octets ist eine Differenz von 56.900 octets
nicht vernachlässigbar?
Falls Du nach einer Erklärung der Unterschiede suchst, sind die
Gemeinsamkeiten vernachlässigbar und nicht die Unterschiede.
Post by Ulf Wendel
Post by Rainer Weikusat
Finde Dich bitte einfach damit ab, daß Du außerstande bist, daß
Interface vernünftig zu benutzen.
Dir ist klar, daß solch ein Satz nur eine Rückfrage provizieren kann ;-).
Wie benutze ich es "richtig"?
Weil ich nicht weiß, wie Du es benutzt hast, kann ich diese Frage
nicht beantworten. Falls Du wissen möchtest, womit das Programm seine
Zeit verbracht hat, solltest Du -O2 und einen profiler benutzen. Der
Sinn von mmap ist im übrigen, nicht gleichzeitig mehrere Kopien
desselben file-Inhaltes im Speicher zu haben und solange Du ohnehin zu
jedem Zeitpunkt nur eine davon hast, sollte sich das bestenfalls
marginal rentieren, falls überhaupt.
Ulf Wendel
2003-10-26 14:53:29 UTC
Permalink
Post by Rainer Weikusat
Post by Ulf Wendel
Bei bummelig 289 Millionen octets ist eine Differenz von 56.900 octets
nicht vernachlässigbar?
Falls Du nach einer Erklärung der Unterschiede suchst, sind die
Gemeinsamkeiten vernachlässigbar und nicht die Unterschiede.
Ah, ich verstehe den Ansatz.

Ich habe nur nicht gewagt in diese Richtung zu denken, weil der
Unterschied weit unter einem Prozent, in der Größenordnung von 2
Promille liegt. Dies schien mir zu unwichtig.
Post by Rainer Weikusat
Post by Ulf Wendel
Post by Rainer Weikusat
Finde Dich bitte einfach damit ab, daß Du außerstande bist, daß
Interface vernünftig zu benutzen.
Dir ist klar, daß solch ein Satz nur eine Rückfrage provizieren kann ;-).
Wie benutze ich es "richtig"?
Weil ich nicht weiß, wie Du es benutzt hast, kann ich diese Frage
nicht beantworten. Falls Du wissen möchtest, womit das Programm seine
Hmm, was brauchst Du von mir? Brauchst Du mehr als:
http://ulf-wendel.de/stuff/client_server.html#compiler
Post by Rainer Weikusat
Zeit verbracht hat, solltest Du -O2 und einen profiler benutzen. Der
Ja, ich könnte einen Profiler verwenden.

Ich ging davon aus, daß meine Frage eine FAQ-Anfängerfrage sei und mir
hier sofort alle sagen: "Dateien zu klein, lies die FAQ unter X",
deshalb war ich "zu faul". Zumal ich mit den Dingern praktisch nicht
umgehen kann.

Egal, ich versuche es mal zu profilen.
Post by Rainer Weikusat
Sinn von mmap ist im übrigen, nicht gleichzeitig mehrere Kopien
desselben file-Inhaltes im Speicher zu haben und solange Du ohnehin zu
jedem Zeitpunkt nur eine davon hast, sollte sich das bestenfalls
marginal rentieren, falls überhaupt.
Hmm, mache ich das? Wenn, dann messe ich hier etwas, was ich nicht
messen möchte. Eigentlich will ich "nur" den Inhalt aus einer Datei in
eine andere "Datei", meine Socketverbindung kopieren. Wofür ich ja auch
schon sendfile() entdeckt habe.

Soweit ich Memory Mapped IO verstanden habe, ist es dafür gedacht mir
eine Datei wie ein Stück Speicher zur Verfügung zu stellen, damit ich
darauf mittels Speicherarithmetik arbeiten kann. Das mache ich hier zwar
nicht, aber der Faktor gegenüber write() wunderte mich trotzdem.

Wenn ich folgendes als Faustregel merken kann, bin ich vollauf
zufrieden: Das Kopieren von Dateien auf ein Socket mittels mmap() ist
für kleine Dateien nicht schneller als mittels read() bei gut gewählter
Blockgröße.

Danke!

Ulf
Rainer Weikusat
2003-10-26 15:19:41 UTC
Permalink
Post by Ulf Wendel
Wenn ich folgendes als Faustregel merken kann, bin ich vollauf
zufrieden: Das Kopieren von Dateien auf ein Socket mittels mmap() ist
für kleine Dateien nicht schneller als mittels read() bei gut
gewählter Blockgröße.
'Das kommt darauf an'. Nämlich darauf, ob das, was Dir mmap erspart
(und zwar 'mehrere Kopien desselben files im Speicher') andernfalls
überhaupt stattfände. Wiederhole die Messung mit 10.000 Prozessen, die
dasselbe file verschicken. Dann kopiert read den Dateiinhalt 10.000
mal und mmap oder sendfile tun das nicht.
Ulf Wendel
2003-10-26 16:05:06 UTC
Permalink
Post by Rainer Weikusat
Post by Ulf Wendel
Wenn ich folgendes als Faustregel merken kann, bin ich vollauf
zufrieden: Das Kopieren von Dateien auf ein Socket mittels mmap() ist
für kleine Dateien nicht schneller als mittels read() bei gut
gewählter Blockgröße.
'Das kommt darauf an'. Nämlich darauf, ob das, was Dir mmap erspart
(und zwar 'mehrere Kopien desselben files im Speicher') andernfalls
überhaupt stattfände. Wiederhole die Messung mit 10.000 Prozessen, die
dasselbe file verschicken. Dann kopiert read den Dateiinhalt 10.000
mal und mmap oder sendfile tun das nicht.
Toller Hinweis, das hätte ich verpennt! Erneut: danke für die Nachhilfe.

Ulf
Loading...