2008-09-29 14 views
33

Ich habe derzeit stark Multi-Thread-Server-Anwendung, und ich bin für einen guten Multi-Thread-Speicherzuordner einkaufen.Multithreaded Memory Allocators für C/C++

  • Suns UMEM
  • Googles tcmalloc
  • Threading Intel Bausteine ​​allocator
  • Emery Berger horten

Von dem, was ich habe:

Bisher bin ich zwischen zerrissen gefunden Hort könnte der schnellste sein, aber ich hatte bis heute nicht gehört, also bin ich skeptisch, wenn es wirklich so gut ist, wie es scheint. Jeder hat persönliche Erfahrung, diese Zuordner auszuprobieren?

+1

Welche spezifisches Problem (e) versuchen Sie mit dem aktuellen Standard-Heap-Manager zu lösen, die Sie verwenden? Und welches ist das? –

+3

Überprüfen Sie in Ihrer Anwendung, ob Sie die Leistung mithilfe von lokalem Threadspeicher verbessern können. Wenn dies möglich ist, können die Gewinne besser sein als die Verwendung eines Multithread-Allokators. – trshiv

Antwort

16

Ich habe tcmalloc verwendet und über Hoard gelesen. Beide haben ähnliche Implementierungen und beide erreichen eine ungefähr lineare Leistungsskalierung in Bezug auf die Anzahl der Threads/CPUs (gemäß den Graphen auf ihren jeweiligen Seiten).

Also: Wenn Leistung wirklich so unglaublich wichtig ist, dann teste Leistung/Belastungstests. Ansonsten würfeln Sie einfach einen Würfel und wählen Sie einen der aufgelisteten (gewichtet nach Benutzerfreundlichkeit auf Ihrer Zielplattform).

Und von trshiv's link, es sieht aus wie Hoard, tcmalloc und Ptmalloc sind alle ungefähr vergleichbar für die Geschwindigkeit. Insgesamt sieht tt so aus, als wäre ptmalloc so optimiert, dass es so wenig Platz wie möglich einnimmt. Hoard ist für einen Kompromiss aus Geschwindigkeit und Speichernutzung optimiert und tcmalloc ist auf pure Geschwindigkeit optimiert.

+1

Der Link von Trshiv ist [hier] (http://dsc.sun.com/solaris/articles/multiproc/multiproc.html) jetzt –

+0

Beide Links sind jetzt gebrochen – Assimilater

4

Vielleicht ist dies der falsche Weg, um sich dem zu nähern, was Sie fragen, aber vielleicht könnte eine andere Taktik insgesamt eingesetzt werden. Wenn Sie nach einem wirklich schnellen Speicherzuordner suchen, sollten Sie vielleicht fragen, warum Sie all die Zeit damit verbringen müssen, Speicher zuzuordnen, wenn Sie vielleicht nur mit der Stapelzuweisung von Variablen davonkommen. Eine Stapelzuweisung, die viel ärgerlicher und richtiger ist, könnte Ihnen viele Mutex-Konflikte ersparen und seltsame Probleme mit der Speicherbeschädigung aus Ihrem Code heraushalten. Außerdem haben Sie möglicherweise weniger Fragmentierung, die helfen könnte.

+0

Wenn es sich um eine Multithread-Umgebung handelt, ist die Stapelzuweisung die Methode, die nur für sehr kleine Objekte in kleinen Mengen verwendet wird. Sie möchten die Stapelgröße eines Threads nicht erreichen, da Sie das gleiche Problem wie bei normaler Speicherbeschädigung haben. – hazzen

+0

Ja, ich stimme Hazzen zu. Die Stapelzuweisung, einschließlich Thread-lokalem Speicher, kann zu Speicherbeschädigung führen, wenn Sie mit großen bis großen Datengrößen arbeiten. – trshiv

3

Wir haben Hort für ein Projekt verwendet, in dem ich vor ein paar Jahren gearbeitet habe. Es schien großartig zu funktionieren. Ich habe keine Erfahrung mit den anderen Allokatoren. Es sollte ziemlich einfach sein, andere auszuprobieren und Lasttests durchzuführen, oder?

5

Ich persönlich bevorzuge und empfehle ptmalloc als Multithread-Allokator. Hoard ist gut, aber in der Auswertung, die mein Team vor ein paar Jahren zwischen Hoard und Ptmalloc gemacht hat, war ptmalloc besser. Soweit ich weiß, gibt es Ptmalloc schon seit einigen Jahren und wird als Multithread-Allokator eingesetzt.

Sie könnten this comparison nützlich finden.

+0

Der verlinkte Artikel wurde [hier] verschoben (http://dsc.sun.com/solaris/articles/multiproc/multiproc.html). –

11

Der einzige Weg, um wirklich zu sagen, welcher Speicherzuordner für Ihre Anwendung richtig ist, ist, ein paar zu versuchen. Alle erwähnten Allokatoren wurden von intelligenten Leuten geschrieben und werden die anderen auf einer bestimmten Mikrobenmark oder der anderen schlagen. Wenn all Ihre Anwendung den ganzen Tag lang malloc ist ein 8-Byte-Chunk in Thread A und frei in Thread B, und braucht nichts anderes zu behandeln, könnten Sie wahrscheinlich einen Speicherzuordner schreiben, der die Hosen aus irgendeinem schlägt die bisher aufgeführten. Für viel mehr wird es nicht sehr nützlich sein. :)

Ich habe einige Erfahrung mit Hoard, wo ich arbeite (genug, so dass eine der eher unbekannten Bugs in der letzten 3.8 Release als Ergebnis dieser Erfahrung gefunden wurde).Es ist ein sehr guter Allokator - aber wie gut, für Sie, hängt von Ihrer Arbeitsbelastung ab. Und Sie müssen für Hoard bezahlen (obwohl es nicht zu teuer ist), um es in einem kommerziellen Projekt ohne GPL-Code zu verwenden.

Ein sehr leicht angepasster ptmalloc2 ist seit geraumer Zeit der Allokator hinter dem malloc von glibc und daher unglaublich weit verbreitet und getestet. Wenn Stabilität vor allem wichtig ist, könnte es eine gute Wahl sein, aber Sie haben es in Ihrer Liste nicht erwähnt, also nehme ich an, es ist out. Für bestimmte Workloads ist es schrecklich - aber das gleiche gilt für alle mallocs für allgemeine Zwecke.

Wenn Sie bereit sind, dafür zu zahlen (und der Preis ist vernünftig, nach meiner Erfahrung), SmartHeap SMP ist auch eine gute Wahl. Die meisten anderen genannten Allokatoren sind als Drop-In malloc/free new/delete-Ersetzungen konzipiert, die LD_PRELOAD'd sein können. SmartHeap kann auch auf diese Art und Weise verwendet werden, aber es enthält auch eine gesamte Zuteilungs-API, mit der Sie Ihre Zuteiler auf den Inhalt Ihres Herzens abstimmen können. In Tests, die wir durchgeführt haben (wiederum sehr spezifisch für eine bestimmte Anwendung), war SmartHeap ungefähr dasselbe wie Hoard für Leistung, wenn es als Drop-In-Malloc-Ersatz fungiert; Der wahre Unterschied zwischen den beiden ist der Grad der Anpassung. Sie können eine bessere Leistung erzielen, je weniger allgemein Sie Ihren Zuweiser benötigen.

Und abhängig von Ihrem Anwendungsfall ist ein Allzweck-Multithread-Allokator möglicherweise nicht das, was Sie überhaupt verwenden möchten. Wenn Sie ständig malloc sind & free'ing Objekte, die alle die gleiche Größe haben, möchten Sie vielleicht nur eine einfache Bramme Allokator schreiben. Die Slab-Zuweisung wird an mehreren Stellen im Linux-Kernel verwendet, die zu dieser Beschreibung passen. (Ich würde Ihnen ein paar nützliche Links geben, aber ich bin ein "neuer Benutzer" und Stack Overflow hat entschieden, dass neue Benutzer nicht zu sein können hilfreich alle in einer Antwort. Google kann jedoch gut genug aushelfen eine späte Antwort auf Ihre Frage, aber

warum mallocs tun, wenn Sie die Leistung hick ups haben

2

Wahrscheinlich.)?

Besser wäre ein Malloc von einem großen Speicherfenster bei der Initialisierung zu tun und dann mit light weight Memory manager, die lease out the memory chunks at run time wäre.

Dies vermeidet jede Möglichkeit von Systemaufrufen, wenn Ihre Heap-Erweiterung.

2

Sie können versuchen, ltalloc (allgemeiner Zweck globalen Speicherzuordner mit Geschwindigkeit der schnellen Pool-Allokator).

3

Der locklessinc Zuordner ist sehr gut und der Entwickler reagiert, wenn Sie Fragen haben. Es gibt einen Artikel, den er über einige der verwendeten Optimierungstricks geschrieben hat, es ist eine interessante Lektüre: http://locklessinc.com/articles/allocator_tricks/. Ich habe es in der Vergangenheit mit hervorragenden Ergebnissen verwendet.

enter image description here