Seite 1 von 1

Performance von fopen unf fread

Verfasst: Do Sep 17, 2015 8:36 pm
von stickybit
Nabend,

ich muss einen ganz einfachen TCP-Server umsetzen. Er soll bei Clientanfragen eine Datei öffnen, deren Inhalt und an den Clinet ausliefern.
Beim Performance-Test ist mir Folgendes aufgefallen. Der Server schafft ca. 9.000 Anfragen pro Sekunde.
Verzichte ich testweise auf fopen unf fread schafft er bis zu 20.000 Anfragen pro Sekunde. Ich habe dann testweise die Datei, aus der gelesen wird, in Ramdisk augelagert.
Das hat das Ergebnis kaum verbessert. Also fopen kostet ca 4.500 Anfragen und das anschließende fread nochmal so viel.

Ich bin ehrlich gesagt etwas enttäuscht vom Ergebnis. Ich frage mich warum das Auslagern der Datei in Ramdisk das Ergebnis nicht verbessert hat.
Bzw. was kann man machen?

Jemand eine Idee?

Schon mal lieben Dank für jeden Hinweis im Voraus!

Liebe Grüße
Andre

Re: Performance von fopen unf fread

Verfasst: Do Sep 17, 2015 8:48 pm
von cloidnerux
Der Server schafft ca. 9.000 Anfragen pro Sekunde.
Verzichte ich testweise auf fopen unf fread schafft er bis zu 20.000 Anfragen pro Sekunde. Ich habe dann testweise die Datei, aus der gelesen wird, in Ramdisk augelagert.
Das hat das Ergebnis kaum verbessert. Also fopen kostet ca 4.500 Anfragen und das anschließende fread nochmal so viel.

Ich bin ehrlich gesagt etwas enttäuscht vom Ergebnis. Ich frage mich warum das Auslagern der Datei in Ramdisk das Ergebnis nicht verbessert hat.
Bzw. was kann man machen?
Anscheinend steckt wohl mehr dahinter, als einfach nur die Daten von der Festplatte an eine Stelle im RAM zu schieben.
Jede Dateioperation geht durch das Betriebssystem, also musst du dir Überlegen, was da passiert.
Du fragst mit fopen eine Datei an. Jetzt muss das Betriebssystem die Anfrage annehmen und verarbeiten. Die Festplatte heraus suchen, durch das Dateisystem hangeln, schauen das die Datei existiert und dein Programm sie mit den angefragten Rechten öffnen kann. Ist das geschehen gibt dir dein OS eine Antwort. Dann fragst du wieder an, und willst jetzt die geöffnete Datei lesen. Prinzipiell steckt ähnlich viel Verwaltungsaufwand dahinter + das tatsächliche Lesen der Daten. Ein ähnliches Problem mit dem Overhead hat man, wenn man ganz viele kleine Dateien kopieren will. Ein 2MB Ordner mit 40k kleinen Dateien kann mitunter 10 mal länger brauchen zum kopieren als ein 1GB Zip.

Praktisch kannst du einfach mal ausprobieren, wie viel schlechter dein TCP Server wird, wenn du die Datei 10 oder 100 mal so groß machst.

Wie kann man es optimieren? Indem man unnötige Dateiaufrufe verhindert. Du schreibst in deinem TCP Server eine Routine, die beim Öffnen die Daten aus einer Datei im Ram hält und nach einer gewissen Zeit der Nichtbenutzung wieder Löscht. Wird die selbe Datei angefragt kannst du sie direkt aus dem Ram senden anstatt sie erneut einzulesen.

Re: Performance von fopen unf fread

Verfasst: Mo Sep 21, 2015 8:16 am
von stickybit
Hallo cloidnerux,

danke für deine ausführliche Erklärung!

LG
Andre

Re: Performance von fopen unf fread

Verfasst: Mo Sep 21, 2015 9:11 am
von Xin
stickybit hat geschrieben:Verzichte ich testweise auf fopen unf fread schafft er bis zu 20.000 Anfragen pro Sekunde. Ich habe dann testweise die Datei, aus der gelesen wird, in Ramdisk augelagert.
Das hat das Ergebnis kaum verbessert. Also fopen kostet ca 4.500 Anfragen und das anschließende fread nochmal so viel.

Ich bin ehrlich gesagt etwas enttäuscht vom Ergebnis. Ich frage mich warum das Auslagern der Datei in Ramdisk das Ergebnis nicht verbessert hat.
Ich denke, die Enttäuschung muss man mal etwas einnorden.

Wenn Du 20000 Anfragen pro Sekunde schaffst - die Anzahl muss man sich auch mal kurz vor Augen führen, das ist ja nicht gerade wenige - dann ist das doch ein recht hoher Wert. Nehmen wir den Aufbau einer PHP-Seite die in der Regel etwa 50-100ms dauert, was 10-20 Anfragen pro Sekunde entspricht.

Wenn Du mit fopen/fread um 9000 einknickst, dann bedeutet das, dass der Verbindungsaufbau schon recht billig ist, denn er kostet offenbar nicht viel mehr als fopen/fread.

Von fclose() schreibst Du nichts. Hast Du nach einer Sekunde 20000 FileHandles?
stickybit hat geschrieben:Bzw. was kann man machen?
Du kannst versuchen den Socket billiger zu machen. Wer schickt denn die Daten? Sind das Tasks oder Threads oder ist das nur ein Thread?

Werden die Threads pro Verbindung aufgesetzt oder wiederverwendet?

Re: Performance von fopen unf fread

Verfasst: Mo Sep 21, 2015 9:32 am
von stickybit
Danke, Xin.
Xin hat geschrieben: Wenn Du mit fopen/fread um 9000 einknickst, dann bedeutet das, dass der Verbindungsaufbau schon recht billig ist, denn er kostet offenbar nicht viel mehr als fopen/fread.
Von fclose() schreibst Du nichts. Hast Du nach einer Sekunde 20000 FileHandles?
fclose() habe ich nicht berücksichtigt. Habe mich vorerst auf fopen unf fread konzentriert, ob da was zu machen ist.
Xin hat geschrieben: Du kannst versuchen den Socket billiger zu machen. Wer schickt denn die Daten? Sind das Tasks oder Threads oder ist das nur ein Thread?
Werden die Threads pro Verbindung aufgesetzt oder wiederverwendet?
Die Daten schickt das Tool queryperf an den Nameserver Bind9, der mit "--enable-threads" kompiliert wurde. Dort werden Threads einmal beim Starten generiert und wiederverwendet.
Ich habe die Aufgabe für den Bind9 ein eigenes Modul zu schreiben. Im Prinzip klappt alles. Nur die Performanceeinbußen aufgrund der Kommunikation mit dem Dateisystem (fopen, fread) haben mich etwas aus der Bahn geworfen. Ich hatte da andere Ergebnisse erwartet. Bzw. dass die Performance-Zahlen nicht so stark zurückgehen. Wir sind ja mit dem Ramdisk im Prinzip schon im RAM. Aber OK, war ein Denkfehler von mir.