Dies ist eine Art Follow-up zu dieser ursprünglichen Frage mit einigen neuen Informationen hinzugefügt. Sehen Sie hier für den ersten Teil, wenn Sie interessiert sind: Struct of arrays, arrays of structs and memory usage patternStruktur der Arrays und Speicherzugriffsmuster
Es scheint, dass es einige Probleme mit meinem ersten Versuch gibt, Struktur von Arrays für eine einfache Klasse einzurichten. Hauptsächlich übermäßige Speicherzuweisung für Zeiger und mögliche Speicherlecks beim Zuordnen dieser Zeiger von vec3_b in der vorherigen Frage.
Ich dachte, wie ich die Daten ohne Pointer neu anordnen könnte, dies erfordert, dass ich zunächst einige Const-Variable für die Größe meiner Daten Buckets, also keine unbegrenzten Werte wie Zeiger, sondern auch die Menge an Speicher auf etwas repariert.
const size_t batch_size = 100;
struct vec3_c
{
size_t x[batch_size];
size_t y[batch_size];
size_t z[batch_size];
};
struct vec3_c vec3_c(size_t x, size_t y, size_t z, size_t index)
{
struct vec3_c v;
v.x[index] = x;
v.y[index] = y;
v.z[index] = z;
return v;
}
struct vec3_c vc3;
for(int i = 0; i < batch_size; i++)
{
vc3 = vec3_c(i+1, i*i, i*10, i);
//printf("vec3c x:%zu, y:%zu, z:%zu\n",vc3.x[i], vc3.y[i], vc3.z[i]);
printf("vec3c x:%p, y:%p, z:%p\n",(void*)&vc3.x[i], (void*)&vc3.y[i], (void*)&vc3.z[i]);
}
---------------x-----------------|----------------y-----------------|----------------z-----------------|
0| 0x7fff57489f40 : 140734657765184 | 0x7fff5748a260 : 140734657765984 | 0x7fff5748a580 : 140734657766784
1| 0x7fff57489f48 : 140734657765192 | 0x7fff5748a268 : 140734657765992 | 0x7fff5748a588 : 140734657766792
2| 0x7fff57489f50 : 140734657765200 | 0x7fff5748a270 : 140734657766000 | 0x7fff5748a590 : 140734657766800
mit diesem aktualisierten Code ich eine feste Behältergröße haben muß, damit ich es eingestellt nur für einfache Zahlen batch_size von 100. Füllen Sie das vec3c mit einigen Daten und führte einen ähnlichen Test durch, dieses Mal scheint es, dass jeder Wert in 8 Byte-Blöcken ausgerichtet ist.
ex:
size of vec3 : 24 bytes
size of vec3a : 24 bytes
size of vec3b : 24 bytes
size of vec3c : 2400 bytes
size of size_t : 8 bytes
size of int : 4 bytes
size of 16 int : 64 bytes
vec3c x:0x7fff592d2f40, y:0x7fff592d3260, z:0x7fff592d3580
vec3c x:0x7fff592d2f48, y:0x7fff592d3268, z:0x7fff592d3588
vec3c x:0x7fff592d2f50, y:0x7fff592d3270, z:0x7fff592d3590
vec3c x:0x7fff592d2f58, y:0x7fff592d3278, z:0x7fff592d3598
vec3c x:0x7fff592d2f60, y:0x7fff592d3280, z:0x7fff592d35a0
vec3c x:0x7fff592d2f68, y:0x7fff592d3288, z:0x7fff592d35a8
vec3c x:0x7fff592d2f70, y:0x7fff592d3290, z:0x7fff592d35b0
vec3c x:0x7fff592d2f78, y:0x7fff592d3298, z:0x7fff592d35b8
vec3c x:0x7fff592d2f80, y:0x7fff592d32a0, z:0x7fff592d35c0
vec3c x:0x7fff592d2f88, y:0x7fff592d32a8, z:0x7fff592d35c8
alle durch 8 Bytes getrennt sind.
Das sollte die Probleme von Speicherlecks und den überschüssigen Speicher für die Zeiger loswerden.
mit diesem neuen Layout würde etwas wie sizeof (vc3 [0] .x) 8 Bytes zurückgeben.
zurück zu den ursprünglichen Fragen:
Ist meine Implementierung von
struct vec3_c
der richtige Weg, eine Struktur von Array-Setup?mit einer Vec_3c Batchgröße von 100 zeigt es 2400 Bytes groß aber jedes einzelne Element ist nur 8 Bytes und richtig ausgerichtet, so dass ich jetzt tatsächlich 8 Elemente auf 1 moderne CPU-Cache-Zeile passen konnte?
würde die Umwandlung von Daten, die mir übergeben werden, in einem typischen Format von nur Arrays von Strukturen die Leistungsvorteile überwiegen, da sie in einem Cache-freundlichen Zustand sind und mehrere Datenpunkte pro Instruktionsaufruf verarbeiten können? Dies ist mit der Einschränkung, dass beide Punkte 1 und 2 korrekt sind.
ex tun das Skalarprodukt zweier Vektoren: , das bedeutet, dass ich das Skalarprodukt 2 vec3_c pro Befehlszyklus bekommen?
bearbeiten eine Frage, wäre es besser, die zusätzlichen 8 Byte Daten hinzufügen, um ein Vielfaches von 32 Bytes machen diese Struktur und vielleicht nutzen, dass weitere 8 Byte als Scratch-Platz oder es einfach leer lassen?
bearbeiten Es wurde mir darauf hingewiesen, dass meine anfängliche Initialisierungsfunktion nur ein Chaos der Dinge machte.Ich kann es auf diese Form aktualisiert:
struct vec3_c* vec3_c()
{
struct vec3_c *v = (struct vec3_c*)malloc(sizeof(struct vec3_c));
v->index = 0;
return v;
}
struct vec3_c* v3 = vec3_c();
for(size_t i = 0; i < batch_size; i++)
{
v3->x[i] = i + 1;
v3->y[i] = i * i;
v3->z[i] = i * 10;
printf("index:%d\tvec3c x:%zu, y:%zu, z:%zu\n",i,v3->x[i], v3->y[i], v3->z[i]);
printf("index:%zu\tvec3c x:%p, y:%p, z:%p\n",i,(void*)&v3->x[i], (void*)&v3->y[i], (void*)&v3->z[i]);
}
Sorry, vielleicht interpretiere ich das ganze Problem falsch, aber es scheint mir, dass Sie vc3 und v falsch verwenden: die Funktion vec3_c reserviert ein lokales (nicht initialisiertes) "v", setzt dann einige Felder und gibt eine Kopie zurück Of v (wessen Felder nicht vorhersagbare Werte enthalten, außer für den Index). Ich sehe, dass Sie in Ihrem Beispiel nicht wirklich an dem Inhalt von vc3 interessiert sind. Was ist der Zweck der Funktion vec3_c? –
@GiuseppeGuerrini mein ursprüngliches Codebeispiel hatte ein paar Fehler, die ich im Laufe der Zeit aussortierte. Ich würde diese Struktur verwenden, um vec3-Werte in einer Stream-Verarbeitung oder SIMD-Anweisungen in Stapelverarbeitung zu verarbeiten. – user1610950