Boost ASIO und Heap Allokation
-
ich habe einen Server mit Boost-ASIO (C++03) mit boost::bind implementiert und dann festgestellt das sich mein Speicherbedarf ständig veraendert (im TaskManager) - das möchte ich gerne komplett vermeiden und habe einen handler_allocator
wie in diesem diesem ASIO-Beispiel:
http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/example/cpp03/allocation/server.cpp
implementiert (und an allen boost::bind stellen verwendet) - nur eben mit einem Fix-Size Pool ohne Rücksprung auf "new"
aber selbst mit dieser Änderung wackelt meine Speicherauslastung immer noch hin/her - besonders schön zu sehen wenn mal mehr als 300 Client verbunden sind
mein Code ist völlig frei von Allokationen jeglicher Art und ich kann ihn leider nicht herzeigen
hat jemand eine Idee
-
jetzt setze ich den allocation_handler server-weit ein - hilft schon mal
und ich brauche noch einen pool für meine Sessionsalso muss ich erstmal etwas umbauen - melde ich nochmal falls das alles nichts hilft
-
Warum ist es überhaupt wichtig dass der "Speicherverbrauch" deines Programms konstant ist?
-
Warum ist es überhaupt wichtig dass der "Speicherverbrauch" deines Programms konstant ist?
Ich versuche Thread-Locking/Deadlock-Probleme in einer Applikation zu "beweisen" - gerade ist die Regel je schneller um so mehr Fehler - ich will die Rate so hoch wie möglich bringen damit mir keiner kommen kann mit "passiert zu selten"
durch die permanente Heap-Allokation wird einfach die Latenz größer
Das Heap-Problem habe ich jetzt gelöst (Pool fuer boost::bind und Pool für Client-Server-Sessions) - rennt wie sau, absolut kein Byte hin oder her
was mir noch auffällt ist das aber der Handle-Count im TaskManager ständig rauf/runtergeht - und ich mache nach meiner Ansicht nach nicht was Windows-Handles benötigt - hat da jemand noch eine Idee
-
Ah, verstehe.
Wundert mich dass das echt so viel Performance bringt - zumindest wenn die Pools selbst Threadsafe sind
(Oder kannst du per-Thread Pools verwenden?)Gast3 schrieb:
was mir noch auffällt ist das aber der Handle-Count im TaskManager ständig rauf/runtergeht - und ich mache nach meiner Ansicht nach nicht was Windows-Handles benötigt - hat da jemand noch eine Idee
Naja, über Handles geht in Windows ziemlich viel.
Eine (nicht vollständige) Liste von Dingen die über Handles angesprochen werden gibt's in der
CloseHandleDoku: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211(v=vs.85).aspxAccess token
Communications device
Console input
Console screen buffer
Event
File
File mapping
I/O completion port
Job
Mailslot
Memory resource notification
Mutex
Named pipe
Pipe
Process
Semaphore
Thread
Transaction
Waitable timerWeiters sind auch bei Sockets Handles im Spiel. Verbindungen zu diversen Geräten oder Kommunikation mit Treibern läuft normalerweise auch über Handles.
Also doch einiges.
Davon werden etliche per Connection anfallen (Socket) und möglicherweise auch welche temporär für diverse Dinge die die ASIO "so zwischendurch" machen muss (vielleicht Waitable timer, Threads, File-Mappings, Events oder so).----
Hast du die Fehlerquelle denn schon gefunden und willst/musst jetzt nur beweisen dass das wirklich Fehler macht (weil du nicht formal beweisen kannst dass es eine Fehlerquelle ist bzw. keiner deiner Kollegen den Beweis nachvollziehen kann)?
Oder bist du nur der Meinung dass es wohl irgendwas in Richtung Deadlock sein wird, ohne den Fehler lokalisiert zu habe?Gibt nämlich auch Tools mit denen sich solche Sachen z.T. recht schnell finden lassen. Das Schöne dabei ist dass man bei den Tools den Fehler nicht unbedingt reproduzieren muss. Wenn das Tool "inkompatible" Locking-Reihenfolge aufzeichnet reicht das normalerweise als Beweis dass ein Fehler vorliegt.
-
Ah, verstehe.
Wundert mich dass das echt so viel Performance bringt - zumindest wenn die Pools selbst Threadsafe sind
(Oder kannst du per-Thread Pools verwenden?)ich hab nur 1 Thread und skaliere über Prozesse, mein Test macht (im Nachtlauf) ohne die ASIO/Allokatoren Optimierung fast 3stellig-Mio Allokationen (168 und 140 byte Blöcke), brauche aber keine Threadsicherheit (da nur ein Thread) daher ist es nur ein Stack mit freiem Speicherplatz in den ich pushe/poppe (schneller gehts nicht)
unnötige dynamische Allokation (sinnvoll) zu verhindern bringt meistens sehr viel - was schlimmeres als new/delete gibt es kaum wenn es um Latenz geht - deswegen hat ASIO ja auch ein Server-Beispiel bei dem gezeigt wird wie man das verhindern kann
Weiters sind auch bei Sockets Handles im Spiel. Verbindungen zu diversen Geräten oder Kommunikation mit Treibern läuft normalerweise auch über Handles.
klar geht viele in Windows über Handles - ich frage mich aber doch warum die ständig im 2 stelligen Bereich auftauchen/wegfallen - ach ja mein Test macht Connect/Disconnect Tests - liegt wohl daran
Hast du die Fehlerquelle denn schon gefunden und willst/musst jetzt nur beweisen dass das wirklich Fehler macht (weil du nicht formal beweisen kannst dass es eine Fehlerquelle ist bzw. keiner deiner Kollegen den Beweis nachvollziehen kann)?
Oder bist du nur der Meinung dass es wohl irgendwas in Richtung Deadlock sein wird, ohne den Fehler lokalisiert zu habe?ich habe mehrere Fehlerquellen gefunden (darf nicht einfach fixen) - die werden "noch" nicht als Fehler von den Kollegen akzeptiert (Fehlerrate noch nicht hoch genug um es als "böse" wahrzunehmen) - mein Tool zeigt permanent Probleme und soll den Widerstand brechen/auswaschen
Gibt nämlich auch Tools mit denen sich solche Sachen z.T. recht schnell finden lassen. Das Schöne dabei ist dass man bei den Tools den Fehler nicht unbedingt reproduzieren muss. Wenn das Tool "inkompatible" Locking-Reihenfolge aufzeichnet reicht das normalerweise als Beweis dass ein Fehler vorliegt.
die Linux-Version zeigt mit dem ThreadSanitizer unsichere Zugriffe von verschiedenen Threads auf Variablen - und mein Test erkennt Deadlocks anhand einer voreingestellten mind. Reaktionszeit
welche Tools meinst du?
-
Kann dir kein spezielles Tool empfehlen, google einfach mal nach "deadlock detector c++".
Gast3 schrieb:
ich hab nur 1 Thread und skaliere über Prozesse, mein Test macht (im Nachtlauf) ohne die ASIO/Allokatoren Optimierung fast 3stellig-Mio Allokationen (168 und 140 byte Blöcke)
Sagen wir 350 Mio Allokationen bei 3,5 GHz. Sagen wir 1000 Zyklen pro Allokation+Deallokation - was mMn. schon grosszügig geschätzt ist, moderne Allokatoren sollten mit wesentlich weniger auskommen.
Dann wären das 100 Sekunden im Allokator verbracht bei 'nem Test der die ganze Nacht läuft. Schreckt mich jetzt nicht.Wenn es sich allerdings so sehr anbietet wie bei dir, dann ist gegen Pools auch nix zu sagen.
Gast3 schrieb:
unnötige dynamische Allokation (sinnvoll) zu verhindern bringt meistens sehr viel - was schlimmeres als new/delete gibt es kaum wenn es um Latenz geht
Halte ich für ne Urban Legend

BTW: Welche Art Software programmiert ihr?
-
Halte ich für ne Urban Legend
eher: für Standard-Applikationen nicht so relevant
oder: die meisten Entwickler haben keine Ahnung wer was wo wie kostet und wenn Sie dann "optimieren" wird es meist schlimmer
nach meiner Meinung ist deine "Urban Legend" eher die Forderung: Schuster, bleib bei deinem Leisten - fürs einfache Entwicklervolk
IO, Heap und Locking sind die 3 Standard-Bösen im Performanz/Latenz-Spiel bei embedded, hochskalierend oder rechenintensiv
und hoher/untypischer Durchsatz zeigt im Threading-Bereich doch immer noch die meisten Probleme auf
Welche Art Software programmiert ihr?
ihr stimmt nicht ganz - eher ein Projekt an dem ich zur Zeit arbeite - Messdatenerfassung mit sehr vielen kleinen Clients
ich arbeite gerne in Projekten wo die Geschwindigkeit/Reaktionsfähigkeit nicht in "schön schnell" gemessen wird also wo Ressourcenmangel oder die geforderte Performanz die 3 Bösen sehr oft zu einem Problem werden lassen