Ich habe gelesen Warum gibt es in C ++ - Zuordnungen keine Neuzuordnungsfunktion? und Ist es möglich, zur Laufzeit ein Array auf dem Heap zu erstellen und dann bei Bedarf mehr Speicherplatz zuzuweisen? , die eindeutig die Neuzuordnung eines dynamischen Array von Objekten angibt ist unmöglich.
In Die C ++ - Standardbibliothek von Josuttis heißt es jedoch, dass ein Allocator, allocator
, eine Funktion allocate
mit der folgenden Syntax hat
wobei hint
eine implementierungsdefinierte Bedeutung hat, die verwendet werden kann, um die Leistung zu verbessern.
Gibt es Implementierungen, die davon profitieren?
Ich habe in meinem plf :: colony C ++ - Container mit Hinweisen mit std signifikante Leistungsvorteile für Iterationszeiten auf kleinen skalaren Typen gewonnen: Allokator unter Visual Studio 2010-2013 (die Iterationsgeschwindigkeit wurde um ~ 21% erhöht) und viel kleinere Beschleunigungen unter GCC 5.1. Man kann also sagen, dass es mit diesen Compilern und std :: allocator einen Unterschied macht. Aber der Unterschied wird compilerabhängig sein. Mir ist das Verhältnis von Hinweis-ignorierenden zu Hinweis-beobachtenden Allokatoren nicht bekannt.
C ++ 11 Staaten, in 20.6.9.1 Zuweiser Mitglieder :
4 - [ Hinweis: In einer Container-Member-Funktion ist die Adresse eines benachbarten Elements oft eine gute Wahl für das Argument
hint
. - Endnote ]
[...]
6 - [...] Die Verwendung vonhint
ist nicht spezifiziert, aber als Hilfe gedacht zur Lokalität, wenn eine Implementierung dies wünscht.
Das Zuweisen neuer Elemente neben oder in der Nähe vorhandener Elemente im Speicher kann die Leistung verbessern, indem die Lokalität verbessert wird. Da sie normalerweise zusammengespeichert werden, neigen benachbarte Elemente dazu, gemeinsam die Speicherhierarchie zu durchlaufen und werden sich nicht gegenseitig vertreiben.
Ich bin mir nicht sicher über bestimmte Implementierungen, aber beachte, dass der Zuweiser den Hinweiszeigerwert nicht zurückgeben darf, bevor er an deallocate
übergeben wurde. Das kann also nicht als primitive Operation verwendet werden, um ein reallocate
zu bilden.
Der Standard sagt, dass der Hinweis von einem früheren Aufruf von allocate
zurückgegeben worden sein muss. Es sagt "Die Verwendung von [der Hinweis] ist nicht spezifiziert, aber es ist
als eine Hilfe für die Lokalität. "Wenn Sie also eine Sequenz von Blöcken ähnlicher Größe in einem Thread zuweisen und freigeben, können Sie den zuvor freigegebenen Wert übergeben, um Cache-Konflikte zwischen Mikroprozessor-Caches zu vermeiden.
Andernfalls, wenn CPU B erkennt, dass Sie Speicheradressen verwenden, die sich noch im Cache von CPU A befinden (auch wenn der Speicher Objekte enthält, die gemäß C ++ zerstört wurden), muss er die Junk-Daten über den Bus weiterleiten. Es ist besser, CPU A und B die jeweils eigenen zwischengespeicherten Adressen wiederverwenden zu lassen.