vector: Immer 4GB reservieren
-
Ein interessanter Blog-Artikel: http://probablydance.com/2013/05/13/4gb-per-vector/.
Im Kern geht es darum, dass der Autor eine Variante von
std::vectorerstellt hat, welche auf einem 64-Bit-OS immer grundsätzlich 4GB Speicher reserviert (andere hohe Werte sind auch denkbar). Dank 64-Bit und der Tatsache, dass das OS die Seiten erst einlagern wird, wenn sie tatsächlich benutzt werden, wird trotzdem weder der virtuelle noch der physikalische Adressraum wirkungsvoll verschwendet.
Die Anwendung hat nun den offensichtlichen Vorteil, dass dervector(normalerweise) niemals vergrößert werden muss, somit nie Elemente kopiert werden müssen.Der Nachteil, den ich spontan sehe (abgesehen von den im Artikel genannten), ist eigentlich nur die Portabilität (kein 32-Bit, keine Betriebssysteme mit virtuellem Speicher etc.), aber man könnte ja diese Strategie trotzdem anwenden, wenn die Voraussetzungen vorliegen (eventuell mit einer seperaten Vektor-Klasse).
Was haltet ihr von der Idee?
-
ipsec schrieb:
Was haltet ihr von der Idee?
Nett, wenn man es braucht. Bisher hatte ich noch nie das Vergnügen, dass Vectorreallocation für mich ein Problem gewesen wäre. Geht das anderen Leuten anders?
-
SeppJ schrieb:
ipsec schrieb:
Was haltet ihr von der Idee?
Nett, wenn man es braucht. Bisher hatte ich noch nie das Vergnügen, dass Vectorreallocation für mich ein Problem gewesen wäre. Geht das anderen Leuten anders?
Bei mir macht laut gprof nicht die Vektorreallokation Probleme, sondern die verschiedensten Kopierkonstruktoren. Ein Grossteil davon müsste von std::vector herrühren. Hab leider gerade kein 64-Bit-System, sonst würde ich das gleich testen.
-
Das sollte man mal mit std::deque vergleichen.
-
4GB Speicher reservieren ist, auch wenn nur die erstem Seite committed wird, viel teurer als ein paar hundert Byte/KB vom Heap zu nehmen. (Steht eh auch schon in dem Blogbeitrag - "bad performance for small vectors").
Genauere Angabe als "viel" kann ich keine liefern, aber der Unterschied wird deutlich sein.Bei billig zu kopierenden (bzw. bei C++ 11: zu movenden) Objekten kann man vermutlich schon ein paar mal umkopieren bevor man mit der 4GB Variante schneller ist.
Wäre aber interessant wie viel es wirklich um ist. Falls jmd. ne Benchmark zu dem Thema machen möchte bitte Ergebnisse hier posten.
-
Es gibt noch ein anderes Problem: Ich habe 4GB Speicher + 4GB swap. Mein Betriebssystem wird bi der allokation des zweiten Vektors merken, dass mein Programm 8GB braucht (die es nicht zur Verfügung hat) und das Programm mit einer bad-alloc exception abschießen. In der Tat merke ich das schon bei wesentlich kleineren Speicherblöcken.
-
Nein, lies den Artikel. Es geht um virtuellen Speicher, nicht um physikalischen.
-
Es geht um (virtuellen) Adressraum, nicht um Speicher.
-
Ich glaube auch nicht, dass Reallokation häufig Bottleneck ist, aber offenbar gibt es Fälle (wie der im Artikel angesprochene), bei denen diese Strategie deutliche Vorteile bringt.
Bleibt immer noch das Problem, dass bei kleineren Vektoren die Performance schlechter ist und dass das ganze nicht portabel ist. Deswegen wäre es wohl (wenn man es denn braucht) das beste, dies als seperate Vector-Klasse (z.B.
bigvector) bereitzustellen, dessen Anwendungsfall große und stark wechselnde Anzahlen von aufwendig zu kopierenden Objekten sind.Noch hübscher wäre natürlich, wenn man
std::vectorper Template-Parameter eine Allokationsstrategie übergeben könnte oder wenn das direkt der Allokater übernehmen könnte.