Warum verwendet der haskell-Enumerator IO so oft sigprocmask?

7

ÜBERARBEITETE ZUSAMMENFASSUNG

Okay, es sieht so aus, als ob die Systemaufrufe sicherlich mit GC zusammenhängen, und das zugrunde liegende Problem ist nur, dass GC zu oft passiert. Dies scheint mit der Verwendung von "splitWhen" und "pack" zu tun zu haben, was ich am besten durch Profiling feststellen kann.

splitWhen's Implementierung konvertiert jeden Chunk von "Lazy" in "Strict" und verkettet sie alle, indem er einen Puffer aus Chunks aufbaut. Das ist eine Menge zuzuteilen.

pack, da es von einem Typ in einen anderen konvertiert, muss zugewiesen werden, und das ist in meiner inneren Schleife, so dass auch Sinn macht.

ORIGINALE AUSGABE

Ich bin auf eine überraschende Syscall-Aktivität in Haskell-Enumerator-basierten IO gestoßen. Hoffe, dass jemand etwas Licht darauf werfen kann.

Ich habe mit einer Haskell-Version eines schnellen Perl-Skripts gespielt, das ich einmal für ein paar Monate geschrieben habe, jetzt und danach. Das Skript liest aus jeder Zeile ein json ein und druckt dann ein bestimmtes Feld aus, falls es existiert.

Hier ist die Perl-Version und wie ich sie ausführe.

%Vor%

Hier ist die Haskell-Version (sie wird ähnlich wie die Perl-Version aufgerufen).

%Vor%

Die Überraschung ist, dass der Trace der Haskell-Version in etwa so aussieht (der eigentliche JSON wird unterdrückt, weil es Daten von der Arbeit sind), während die Perl-Version das tut, was ich erwarten würde; eine Reihe von Reads gefolgt von einem Schreiben, wiederholt.

%Vor%     
tehgeekmeister 23.04.2012, 01:16
quelle

4 Antworten

7

Sind Sie besorgt über die Zuweisungen oder die (Overhead von?) Aufrufe an sigprocmask?

Wenn es ersteres ist und Sie das enumerator -Paket verwenden möchten, hilft diese kleine Änderung einem 4k-Testsatz um etwa 50%: 8MB Zuweisungen auf 4MB und gen0 GCs von 15 auf 6 reduziert.

%Vor%

Vorher (stats von +RTS -sstderr -RTS ):

%Vor%

Nachher: ​​

%Vor%

Was eine ziemlich vernünftige Verbesserung ist, aber definitiv etwas zu wünschen übrig lässt. Anstatt den Enumerator zu sehr in den Wahnsinn zu treiben, habe ich einen Stich gemacht, um es in Conduit-0.4.1 nur für Tritte neu zu schreiben. Es sollte gleichwertig sein ...

%Vor%

... aber aus irgendeinem Grund reserviert und speichert weniger Speicher:

%Vor%     
Nathan Howell 23.04.2012, 06:17
quelle
7

Dies wird auf oberster Ebene von Kommentaren unterstützt:

  

FWIW, ich gehe durch die Laufzeit (wir diskutieren das auch im IRC) und es gibt nur zwei Anwendungen von sigprocmask: GC und der tty-Treiber. Letzteres ist unwahrscheinlich, ich habe Profiling empfohlen, um zu verifizieren, dass es viel GC macht und zu versuchen, herauszufinden, warum.

Und es stellt sich heraus (von IRC), dass es 90MB Zuteilung für 0.5MB Daten macht, und der Müllsammler wird in der Tat ziemlich viel ausgelöst. Jetzt liegt es also daran, warum der Enumerator so viel zusätzliche Zuweisung vornimmt.

    
geekosaur 23.04.2012 03:45
quelle
4

Wenn die Menge der Daten, die zwischen diesen Sigsetmasken gelesen werden, groß ist, ist die erste Vermutung in meinem Kopf, dass die Laufzeit die Sigsetmask ausführt, bevor der GC läuft, so dass GC nicht unterbrochen wird, wenn der Heap inkonsistent ist Staat.

    
none 23.04.2012 03:01
quelle
3

Mehr als ein Kommentar und weniger als eine Antwort: Wenn Sie durch die GHC-Quelle grepsen, sehen Sie posix/TTY.c (TERMIOS-Code) und sm/GC.c (via {,un}blockUserSignals ) die wahrscheinlichsten Kandidaten. Sie könnten GHC mit Debugging-Symbolen kompilieren oder einfach einige (einmalige) Dummy-Systemaufrufe einwerfen, um sicherzustellen, dass Sie die beiden Systemaufrufprofile unterscheiden können, um das herauszufinden. Ein weiterer günstiger Test wäre, alle terminalen Interaktionen zu entfernen, und wenn das Maskierungsverhalten verschwindet, wäre dies ein leichter Beweis, der den GC unterstützt (keine Antwort).

EDIT: Ich sollte anerkennen, dass ein bibliothekscode sigprocmask auch aufrufen kann, ignorierte ich das als eine weniger wahrscheinliche Quelle, aber es könnte tatsächlich das Problem sein!

    
Thomas M. DuBuisson 23.04.2012 03:35
quelle

Tags und Links