Schnellste Möglichkeit zum Lesen/speichern viele mehrdimensionale Daten? (Java)
Ich habe drei Fragen zu drei geschachtelte Schleifen:
for (int x=0; x<400; x++)
{
for (int y=0; y<300; y++)
{
for (int z=0; z<400; z++)
{
//compute and store value
}
}
}
Und ich speichern müssen alle berechneten Werte. Mein standard-Ansatz wäre die Verwendung eines 3D-array:
values[x][y][z] = 1; //test value
aber dieser entpuppt sich langsam: es dauert 192 ms bis komplette diese Schleife, wo eine einzelne int-Zuweisung
int value = 1; //test value
dauert nur 66 ms.
1) Warum ist ein array, also relativ langsam?
2) Und warum wird es sogar langsamer, wenn ich diese in der inneren Schleife:
values[z][y][x] = 1; //(notice x and z switched)
Diese dauert mehr als 4 Sekunden!
3) am wichtigsten: Kann ich mit einer Daten-Struktur, die ist so schnell wie die Zuordnung einer einzelnen ganzen Zahl, aber speichern kann so viel Daten wie der 3D-array?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als andere Spitzen, die Sie vergleichen äpfel mit Birnen. Die dreifach-array ist zu langsam-da braucht es zu dereferenzieren (innerlich zumindest - ja, "es gibt keine Pointer in Java") drei mal; aber dann wieder, Sie kann nicht auf eine einzige integer-variable...
Weil Sie abgenommen haben cache-Kohärenz. Die schnellsten verändernden Indizes sollen die letzten sein, so dass die meisten Speicherzugriffe auftreten, die nebeneinander innerhalb der gleichen cache-Blöcken, stattdessen zwingen Sie Ihren Prozessor zu warten, bis die Blöcke werden gelesen aus dem Haupt-RAM.
Nicht. Es gibt keine solche Struktur, da die integer-variable passt in eine Maschine registrieren (sogar schneller als der Prozessor-Speicher-cache), und kann immer zugegriffen werden, schneller als alles, was Sie kümmern zu erwähnen. Prozessor-Geschwindigkeiten sind um ein Vielfaches schneller als Hauptspeicher beschleunigt. Wenn Ihr 'working set' (die Daten, die Sie benötigen, um den Betrieb auf) passt nicht in die Register-oder cache-Speicher, müssen Sie eine Strafe bezahlen, um es zu Holen aus dem RAM (oder noch schlimmer, Scheibe).
Diesem wird gesagt, Java hat Grenze prüft bei jedem array-Zugriff, und scheint nicht zu schlau zu sein über die Optimierung der überprüfung von Grenzen entfernt. Der folgende Vergleich von Interesse sein können:
Die Ausgabe auf meinem system, ist
Daher ist es etwas Raum für Verbesserung... aber ich glaube wirklich nicht, es lohnt sich.
Lief mit -Xmx1g
Zeit: 0.188 Sekunden.
Scheint verdammt schnell.. Sie sind auf der Suche 48 MILLIONEN Elemente in der innersten Schleife.
Homerolling eine dumme kleine datastructure..
Zeit: 0.925 Sekunden.
Welche schneller ist als 4 Sekunden, die Sie hatten in der gemischten Reihenfolge Beispiel.
Denke ich, dass multi-arrays sind zu viel für das problem. Sie sind besser dran mit einer komplexeren Datenstruktur, wie Sie halten die Sachen all in 1 memory location (x,y,z,Wert).
Java ist eine OO Sprache. In den meisten Fällen sollten Sie die Objekte, und nicht komisch Datenstrukturen wie int[][][]
Haben Sie versucht das:
könnte es verbessern Sie Ihre cache-thrashing.
Ich würde vermuten, dass dies hat eine Menge zu tun mit der Zwischenspeicherung und registriert und das Prinzip der Speicher Ort.
Java hat Zugriff auf Tausende von bytes mehr Speicher, wenn die Speicherung in einem array. Mit der einzigen variable, es kann nur halten Sie diesen Wert in den cache und nur halten Sie es aktualisieren.
Der cache ist nicht groß genug für die ganze multi-dimensionalen array, also Java hat immer die Aktualisierung den cache und aus dem Speicher. Cache-Zugriffszeiten sind viel schneller als memory access times.
Ich gar nicht sehen, warum würden Sie dies tun test, obwohl. Wenn Sie brauchen, um zu speichern eine Vielzahl von Daten in ein mehrdimensionales array, die Verwendung einer einzigen variable nicht hilfreich, auch wenn es schneller ist.
Auch der Grund dafür, dass, wenn der Parameter eingeschaltet, um beim Zugriff auf das array ist, weil Sie springen, um im Speicher viel mehr (viel mehr cache-misses), als wenn Sie einfach Durchlaufen in die andere Richtung.
Wenn man bedenkt, dass das array ist riesig, die Menge an Arbeitsspeicher verwendet wird, die indirections benötigt (ein mehrdimensionales array ist ein arrays von Referenz auf array...), das scheint nicht bei allen langsam zu mir. Wenn Sie den Schalter x und z sind Sie wahrscheinlich löschen den cache.
Als Vergleich könnte man alles speichern in einem flachen array.... Dies verbessert die Speicherung der Geschwindigkeit... aber dann ist der Abruf wäre komplexer und viel langsamer.