Eine Änderung in meiner Bibliothek hat es viel langsamer gemacht. Profiling hilft mir nicht. Was könnte der Grund für die Verlangsamung sein?

9

Mein Problem, kurz

Ich habe eine Änderung an meiner Bibliothek vorgenommen, jetzt ist es viel langsamer, aber ich kann nicht herausfinden, wo sie all diese zusätzliche Zeit verbringt. Profilberichte helfen nicht. Bitte helfen Sie mir herauszufinden, was der Grund sein könnte.

Irgendein Kontext

Ich habe eine Redis-Client-Bibliothek namens Hedis erstellt und ein Benchmark-Programm dafür erstellt. Nun habe ich einige interne Änderungen an der Bibliothek vorgenommen, um die Architektur zu bereinigen. Dies führte dazu, dass die Leistung (in Redis-Anfragen pro Sekunde, gemessen am Benchmark) um etwa den Faktor 2,5 sank.

Der Benchmark öffnet 50 Netzwerkverbindungen zu einem Redis-Server auf localhost. Die Verbindungen werden zwischen den beiden Versionen unterschiedlich gehandhabt:

  • Die schnelle Version verwendet einen Thread pro Verbindung (der Benchmark hat also 50 Threads, die gleichzeitig ausgeführt werden). Es liest aus dem Sockel handle mit unsafeInterleaveIO (ich beschreibe meinen Ansatz in Striche in einem Blogpost hier ). Ich war ein bisschen unglücklich mit der Architektur, also änderte ich die Dinge zu
  • Die langsame Version , die drei Threads pro Verbindung verwendet. Sie kommunizieren über zwei Chan s (150 Threads, die im Benchmark ausgeführt werden).

Einige weitere Informationen, die relevant sein könnten:

  • Kompiliert mit GHC 7.2.2.
  • Das Benchmark-Programm ist zwischen den beiden Versionen unverändert, also Netzwerk der Verkehr ist der gleiche.
  • Beide Versionen verwenden die single-threaded-Laufzeit (kompiliert ohne -threaded ).
  • Alle Threads werden durch Aufruf von forkIO erstellt. Nicht desto teurer forkOS .

Profilergebnisse

Profiling gibt mir keinen klaren Grund für den Leistungsabfall. Laut dem Profiling-Bericht verbringen beide Versionen mehr als 99% ihrer Zeit in System.IO.hFlush und Data.ByteString.hGetSome . Die Anzahl der Aufrufe von hFlush und hGetSome ist in beiden Versionen gleich. Da der Netzwerkverkehr in beiden Fällen ebenfalls gleich ist, können diese Funktionen nicht der Grund für die Verlangsamung sein.

Der einzige signifikante Unterschied, den ich zwischen den beiden Versionen messen kann, ist, was time (das Unix-Dienstprogramm) mir sagt: Die langsame Version (mit dreimal so vielen Threads) verbringt wesentlich mehr Zeit in "sys" als in "user" ", verglichen mit der schnellen Version. Das GHC +RTS -s Flag meldet dies als reduzierte Produktivität.

Hier sind die Programmausgaben für beide Versionen mit dem +RTS -s Flag:

Benchmark der schnellen Version

%Vor%

Benchmark der langsamen Version

%Vor%

Haben Sie irgendwelche Ideen oder Hinweise, woher diese zusätzliche Zeit kommen könnte?

    
informatikr 31.01.2012, 10:17
quelle

2 Antworten

3

Laut dem Profiling-Bericht wird die meiste Zeit in hFlush und hGetSome verbracht. Laut time benötigt die langsame Version viel mehr Systemzeit. Also, meine Hypothese ist, dass viel Zeit blockiert und abgewartet wird, ob es auf mehr Input wartet oder Threads gesperrt und entsperrt wird.

Hier ist das erste, was ich tun würde: kompilieren Sie den Code mit -threaded und sehen Sie, was passiert. Die Thread-Laufzeitumgebung verwendet einen komplett anderen IO-Manager, und ich vermute stark, dass diese einzelne Änderung Ihr Problem beheben wird.

    
John L 01.02.2012 10:54
quelle
2

Mein rate wäre, dass es etwas mit dem Overhead von Chan zu tun hat.

Mein erster Gedanke war eine erhöhte GC-Zeit, aber das scheint überhaupt nicht der Fall zu sein. Mein zweiter Gedanke ist, dass vielleicht das gesamte Sperren und Freigeben bei der Verwendung von Chan (das über MVar implementiert ist) das Problem ist. Aber das ist nur eine Vermutung.

Sie könnten stattdessen TChan (d. h. STM) ausprobieren und sehen, ob das den geringsten Unterschied macht. (Vielleicht könnten Sie ein kleines Skelett kodieren, nur um die beiden zu vergleichen und zu sehen, ob das Problem dort liegt, anstatt Ihren "echten" Code neu zu implementieren.)

Ansonsten habe ich keine Ideen mehr.

    
MathematicalOrchid 31.01.2012 11:03
quelle

Tags und Links