Schnellere Heap Implementierung für MSVC gesucht
-
Der Visual-Studio Heap (Allocator) ist ja nicht gerade der schnellste...
Ich suche nun eine Heap-Implementierung, mit der wir einige Programme die sehr oft Speicher anfordern und wieder freigeben etwas beschleunigen könnten.
Ideal wäre etwas, was wir nur in den .EXEn einbinden müssen - die ganzen (hauseigenen) DLLs zu modifizieren wäre ... naja, das kommt nicht wirklich in Frage.
Je einfacher das Ding einzubinden ist, und je schneller es ist, desto besser
Kann mir jemand Tips geben was sich da auszahlen würde anzusehen?
-
Ich weiss nicht ob Du da was finden wirst, ohne Aufwand...
Die CRT hat ja selber keinen MemoryManager sondern verwendet einfach den Win-Heap (HeapAlloc / i.d.R. heute ja den LFH; zumindest ab Vista per Default).Ein Tipp kan ich Dir leider keinen geben, da mir noch keines Aufgefallen ist, was sich wirklich lohnt anzuschauen... für meine Echtzeitanwendungen hat der LFH bisher immer ausgereicht... das ist zumindest eine riesige Steiegerung im Vergleich zu XP...
Siehe auch hier:
http://stackoverflow.com/questions/4090971/dlmalloc-crash-on-win7Aber es gibt ja auch viele Ansätze:
http://zeuxcg.blogspot.com/2009/03/fighting-against-crt-heap-and-winning.htmlHier die Versuche von Mozilla:
https://bugzilla.mozilla.org/show_bug.cgi?id=407459
http://benjamin.smedbergs.us/blog/2008-01-10/patching-the-windows-crt/Hier noch was theoretisches... wobei das schon von 2002 stammt und es sich in dem Bereich wohl noch einiges getan hat...
http://www.cs.umass.edu/~emery/pubs/berger-oopsla2002.pdf
-
Oha, Sorry!
Studio = Visual Studio 2005
OS = Windows XP embedded SP2 x86
-
Du kannst normal den LFH aktivieren, falls dies nicht mit VS2005 schon gemacht wird (hab nicht nachgeschaut); sollte ab XP SP2 vom OS unterstützt werden (man muss dazu AFAIK keine spezielle Komponenten einbinden)
Siehe dazu auch:
http://msdn.microsoft.com/en-us/library/csd157zx(VS.80).aspx
-
Ja, es sieht so aus, als ob VC2005 den LFH nicht per default einschaltet.. muss Du also machen... siehe vorheriges Post...
Nur zur Info:
http://www.abstraction.net/content/articles/analyzing the heaps of a win32 process.htm
-
Ist der LFH denn schneller als der "normale" Heap?
"Low fragmentation" klingt für mich eher nach "mehr Aufwand" = langsamerAusprobieren werd' ich's natürlich auf jeden Fall.
Ansonsten werd' ich denk' ich einfach mal gucken was mit dem Hoard so geht. Der sieht akzeptabel einfach einzubinden aus. Zumindest mal gucken was es bringen würde (bzw. ob überhaupt). Ob meinen Cheffchen das die 20K Wert ist, ist natürlich wieder ne andere Frage.
Daher wäre ich auch froh falls jmd. günstigere Alternativen wüsste.
-
Wenn Du viele Allokationen hast fragmentiert dieser nicht so und ist somit wesentlich schneller
-
Ah. Das auch logisch klingen tun
Die zentrale "eine für alle Threads" Critical-Section die bei jeder Heap Allocation gelockt werden muss gibt's aber immer noch, oder?
(Also im Gegensatz zu Allokatoren wie dem tcmalloc und ähnlichen Biestern)Und... zahlt es sich aus mit der _set_sbh_threshold() Funktion rumzuspielen, oder ist das vergebene Liebesmüh'?
-
AFAIK wird der sbh ab VS2005 nicht mehr verwendet... und wenn Du den LFH verwendest kommen sich die beiden eh nur die die Quere! ALso bitte nicht einschalten!
-
Ja, in deinem 2. Link steht dass der SBH "Schwellwert" bei VC8 per Default 0 ist, was den SBH deaktiviert.
Hatte mir schon fast gedacht dass SBH + LFH = nicht so gute Idee
-
Im Übrigen erstmal Danke, Jochen!
Hab jetzt nochwas selbst gefunden:
http://stackoverflow.com/questions/858592/windows-malloc-replacement-e-g-tcmalloc-and-dynamic-crt-linkingDer "nedalloc" sieht interessant aus:
http://www.nedprod.com/programs/portable/nedmalloc/
-
Hmpf.
Der "nedmalloc" mag mich nicht.
Da ist ne fertige DLL dabei, aber die funktioniert nicht - zumindest nicht mit dem "windows patcher".
Die Patch-Funktion gibt "1" zurück, aber es wird nix schneller in meinem kleinen Benchmark-Programm.Wenn ich dagegen den LFH aufdrehe wird es merklich schneller.
Hmpf.@Jochen
Spricht etwas dagegen das LFH Flag auch für den "Process-Heap" aufzudrehen?
Ich verwende den Process-Heap selbst nicht, aber vielleicht gibt es ja diverse Windows DLLs die sich da bedienen - dachte mir wenn dann gleich bei beiden Heaps.
-
Der LFH kann man normal für alle Heaps verwenden... wüsste nicht was dagegen sprechen sollte...
-
Warum genau müsst ihr denn so viel allokieren? Sind das vielleicht lauter gleichartige Objekte?
-
Weil das eben so ist
Und nein, einfach nen Pool reinwerfen ist nicht.Da läuft ein Prozess. In den werden bei bedarf DLLs reingeladen. Jede DLL ist ein Spiel. Wenn der Spieler Spiel wechselt wird die DLL rausgeworfen und ein neues Spiel (andere DLL) geladen.
Jedes Spiel baut sich seinen Szenen-Graphen komplett neu auf, mitsamt der vielen tausend Objekte die man dazu braucht.
Es werden std::vector und std::string verwenden und auch ab und an mal rumkopiert/returned/... (speziell Strings).
Dinge ebenDa anzufangen irgendwas umzuschreiben ist nicht. Das sind viele viele VIELE Projekte (LIBs, DLLs, ein paar EXEn) mit insgesamt vermutlich weit über 200 KLOC.
Und da das ganze nach ein paar Spiel-Wechseln anfängt langsamer zu werden, liegt die Vermutung nahe, dass da was fragmentiert. (Vor allem da der Handle-Count, Speicherverbrauch etc. sich halbwegs gut auf einem Wert einpendelt - echtes Leak ist hier also eher keines am Werk). LFH könnte schon mal helfen - am echten Patienten konnte ich es noch nicht probieren. Und wenn der Allocator nebenbei zusätzlich schneller wird, wäre das natürlich ein zusätzlicher Bonus.
Davon abgesehen war mir der doch relativ langsame Allocator von MSVC immer schon ein Dorn im Auge. Wobei sich ja jetzt herausgestellt hat, dass hier nicht MSVC Schuld ist, sondern unser betagtes Windows XP.
Insbesondere da ich weiss, dass es schon länger wesentlich schnellere Allocator gibt - tcmalloc, ptmalloc etc. Darum will ich auch gar nicht wahnsinnig viel Zeit in etwas investieren (=manuell zu poolen anfangen oder was weiss ich), was eigentlich nicht nötig ist, und spätestens mit dem angeblich turboschnellen Allocator von Windows 7 keinen Sinn mehr machen wird. Weil man dabei kaum noch was gewinnt.
----
Da nedmalloc zumindest behauptet mit den schnellsten Allokatoren mithalten zu können, dachte ich mir das wäre ne feine Sache. WENN ich es denn zum Laufen bringen würde
-
hustbaer schrieb:
Und da das ganze nach ein paar Spiel-Wechseln anfängt langsamer zu werden, liegt die Vermutung nahe, dass da was fragmentiert. (Vor allem da der Handle-Count, Speicherverbrauch etc. sich halbwegs gut auf einem Wert einpendelt - echtes Leak ist hier also eher keines am Werk).
Besteht vielleicht die Möglichkeit jeder dll ihren eigenen Heap zu geben und den beim Spielwechsel einfach komplett wegzuwerfen?
Oder könnte man jede dll vielleicht in einem separaten Prozess hosten, statt alle im selben?
-
dot schrieb:
hustbaer schrieb:
Und da das ganze nach ein paar Spiel-Wechseln anfängt langsamer zu werden, liegt die Vermutung nahe, dass da was fragmentiert. (Vor allem da der Handle-Count, Speicherverbrauch etc. sich halbwegs gut auf einem Wert einpendelt - echtes Leak ist hier also eher keines am Werk).
Besteht vielleicht die Möglichkeit jeder dll ihren eigenen Heap zu geben und den beim Spielwechsel einfach komplett wegzuwerfen?
Nö.
Wüsste nicht wie ich das dem MSVC beibringen sollte. Ausserdem haben die DLLs C++ Interfaces, und es ist nicht garantiert dass alles was die DLL alloziert auch mit ihr sterben geht.Oder könnte man jede dll vielleicht in einem separaten Prozess hosten, statt alle im selben?
Ja, mit gröberen Umbauarbeiten = no-go im Moment.
-
Schon mal daran gedacht in kritischen Klassen einen Pool-Allokator zu verwenden?