Eine etwas längere Antwort, die erklärt, warum es effizienter ist, den Index am schnellsten zu ändern. Es gibt zwei wichtige Dinge, die Sie verstehen müssen.
Erstens speichert MATLAB (und Fortran, aber nicht C und die meisten anderen Programmiersprachen) Arrays im Speicher in "Spaltenhauptreihenfolge". Beispiel: Wenn A eine 2 × 3 × 10-Matrix ist, werden die Einträge in der Reihenfolge gespeichert
A (1,1,1)
A (2,1,1)
A (1,2,1)
A (2,2,1)
A (1,3,1)
A (2,3,1)
A (1,1,2)
A (2,1,2)
...
A (2,3,10)
Diese Wahl der Spalten-Hauptreihenfolge ist willkürlich - wir könnten einfach eine "Zeilen-Hauptreihenfolge" -Konvention übernehmen, und genau das wird in C und einigen anderen Programmiersprachen gemacht.
Die zweite wichtige Sache, die Sie verstehen müssen, ist, dass moderne Prozessoren nicht auf einen Speicherplatz gleichzeitig zugreifen, sondern "Cache-Zeilen" von 64 oder sogar 128 zusammenhängenden Bytes (8 oder 16 Gleitkommazahlen mit doppelter Genauigkeit) laden und speichern. zu einer Zeit aus dem Gedächtnis. Diese Datenblöcke werden vorübergehend in einem schnellen Speichercache gespeichert und bei Bedarf zurückgeschrieben. (In der Praxis ist die Cache-Architektur jetzt mit bis zu 3 oder 4 Ebenen des Cache-Speichers ziemlich kompliziert, aber die Grundidee lässt sich mit einem einstufigen Cache erklären, wie er früher auf Computern verwendet wurde.)
EIN
Wenn die Schleifen so verschachtelt sind, dass die innerste Schleife den Zeilenindex aktualisiert, wird auf die Array-Einträge in der Reihenfolge A (1,1), A (2,1), A (3,1), ... zugegriffen Wenn auf den ersten Eintrag A (1,1) zugegriffen wird, bringt das System eine Cache-Zeile, die A (1,1), A (2,1), ..., A (8,1) enthält, aus dem Hauptspeicher in den Cache . Die nächsten 8 Iterationen der innersten Schleife verarbeiten diese Daten ohne zusätzliche Hauptspeicherübertragungen.
Wenn wir die Schleifen alternativ so strukturieren, dass der Spaltenindex in der innersten Schleife variiert, wird auf die Einträge von A in der Reihenfolge A (1,1), A (1,2), A (1,3) zugegriffen ), ... In diesem Fall würde der erste Zugriff A (1,1), A (2,1), ..., A (8,1) aus dem Hauptspeicher in den Cache bringen, jedoch 7/8 von Diese Einträge würden nicht verwendet. Der Zugriff auf A (1,2) in der zweiten Iteration würde dann weitere 8 Einträge aus dem Hauptspeicher einbringen und so weiter. Wenn der Code in Zeile 2 der Matrix funktioniert, wird der Eintrag A (2,1) möglicherweise aus dem Cache entfernt, um Platz für andere benötigte Daten zu schaffen. Infolgedessen generiert der Code 8-mal so viel Verkehr wie erforderlich.
Einige optimierende Compiler können Schleifen automatisch umstrukturieren, um dieses Problem zu vermeiden.
Viele numerische lineare Algebra-Algorithmen für die Matrixmultiplikation und -faktorisierung können optimiert werden, um je nach Programmiersprache effizient mit dem Reihen- oder Spalten-Hauptordnungsschema zu arbeiten. Eine falsche Vorgehensweise kann die Leistung erheblich beeinträchtigen.
For
Schleifen sind in MATLAB sehr langsam. Sie sollten explizite Schleifen in MATLAB nach Möglichkeit vermeiden. Stattdessen kann ein Problem normalerweise in Form von Matrix- / Vektoroperationen ausgedrückt werden. Das ist der MATLABIC-Weg. Es gibt auch eine Menge eingebauter Funktionen zum Initialisieren von Matrizen usw. Beispielsweise gibt es eine Funktion ones () , die alle Elemente einer Matrix auf 1 setzt (durch Erweiterung, durch Multiplikation auf einen beliebigen Wert) (einen Skalar) multipliziert mit der All-Ones-Matrix)). Es funktioniert auch auf 3-D-Arrays (was meines Erachtens das Beispiel hier abdeckt).