Ich schreibe ein Programm (in C ++), in dem ich Arrays zuweisen muss, deren Startadressen mit der Cache-Zeilengröße übereinstimmen sollen. Wenn ich diese Arrays zuteile, möchte ich auch, dass der Speicher auf Null initialisiert wird.
Momentan funktioniert es mit der posix_memalign-Funktion. Dies funktioniert gut, um Arrays mit Speicherausrichtung zu erhalten, aber die Arrays sind nicht initialisiert. Gibt es eine bessere Funktion, die ich verwenden kann, um die Arrays auf Null zu setzen, wenn ich sie initialisiere, oder muss ich mich einfach damit begnügen, eine separate Schleife zu schreiben, um es für mich zu tun?
Rufen Sie einfach memset
auf dem Block auf. Stellen Sie sicher, dass Sie den Zeiger nicht auf einen Typ anwenden, für den die Festlegung teuer ist (wie char *
), bevor Sie memset
aufrufen. Da der Zeiger ausgerichtet wird, stellen Sie sicher, dass Informationen nicht vom Compiler verborgen sind.
Aktualisieren : Um meinen Punkt zu verdeutlichen, dass die Ausrichtung nicht ausgeblendet wird, vergleiche:
%Vor% Mit GCC
, mem_demo_1
wird auf 60 Zeilen der Assembly kompiliert, während mem_demo_2
mit 20 kompiliert wird. Der Leistungsunterschied ist ebenfalls enorm.
Mit GCC kompiliert mem_demo_1 zu 60 Zeilen der Assembly, während mem_demo_2 zu 20 compiliert. Der Leistungsunterschied ist ebenfalls enorm.
Ich habe beschlossen, diese Aussage auf Linux 2.6.32 mit gcc 4.4.6 zu überprüfen. Zuerst
mem_demo_1 kompiliert zu 60 Zeilen der Assembly, während mem_demo_2 kompiliert wird bis 20
.
Dies ist der Test (in Datei main.c):
%Vor%Wenn ich kompiliere:
%Vor%Ich sehe, dass es in mem_demo_1 nur 8 Zeilen gibt:
%Vor%Ich sehe, dass es in mem_demo_2 nur 11 Zeilen gibt:
%Vor%Also, "mem_demo_1 kompiliert zu 60 Zeilen der Assembly, während mem_demo_2 zu 20 kompiliert" kann nicht bestätigt werden.
Wenn ich kompiliere:
%Vor%gcc verwendet eine eigene Implementierung von memset und beide Funktionen mem_demo_1 und mem_demo_2 sind größer:
%Vor%Jedoch kann "mem_demo_1 kompiliert zu 60 Zeilen Assembly, während mem_demo_2 kompiliert zu 20" nicht bestätigt werden.
Sekunde
"Der Leistungsunterschied ist auch enorm"
Ich habe main.c erweitert, um viele Schleifen mit memset zu machen. Ich sehe auch nicht, dass Memes in mem_demo_1 langsamer ist als mem_demo_2.
Dies ist von Linux Perf-Berichten:
mem_demo_2 gibt 8,37% in memset aus:
8,37% main.perf.no_bu libc-2.12.so [.] __memset_sse2
während mem_demo_1 7,61% in memset ausgibt:
7.61% main.perf.no_bu libc-2.12.so [.] __memset_sse2
Und das sind Messungen selbst:
%Vor% Übrigens zeigt gcc -fverbose-asm -c -S -O3
mir Assembler für mem_demo_2:
Tags und Links c c++ posix memory-alignment dynamic-allocation