Una risposta un po 'più lunga che spiega perché è più efficiente far variare più rapidamente l'indice più a sinistra. Ci sono due cose chiave che devi capire.
In primo luogo, MATLAB (e Fortran, ma non C e la maggior parte degli altri linguaggi di programmazione) memorizza gli array in memoria in "ordine maggiore di colonna". ad es. se A è una matrice 2 per 3 per 10, le voci verranno memorizzate nell'ordine
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)
Questa scelta di ordine maggiore di colonna è arbitraria, potremmo semplicemente adottare una convenzione di "ordine maggiore di riga", e in effetti è ciò che viene fatto in C e in altri linguaggi di programmazione.
La seconda cosa importante che devi capire è che i moderni processori non accedono alla memoria una posizione alla volta, ma piuttosto caricano e memorizzano "linee di cache" di 64 o addirittura 128 byte contigui (8 o 16 numeri in virgola mobile a precisione doppia) alla volta dalla memoria. Questi blocchi di dati vengono temporaneamente archiviati in una cache di memoria veloce e riscritti secondo necessità. (In pratica l'architettura della cache è ora piuttosto complicata con fino a 3 o 4 livelli di memoria cache, ma l'idea di base può essere spiegata con una cache a un livello del tipo che i computer avevano ai miei tempi più giovani.)
Supponiamo ora che sia un array con 10.000 righe e colonne e che sto eseguendo il ciclo su tutte le voci. A
Se i loop sono nidificati in modo tale che il loop più interno aggiorni il pedice di riga, si accederà alle voci dell'array nell'ordine A (1,1), A (2,1), A (3,1), ... Quando si accede alla prima voce A (1,1), il sistema porterà una cache contenente A (1,1), A (2,1), ..., A (8,1) nella cache dalla memoria principale . Le successive 8 iterazioni del ciclo più interno funzionano su questi dati senza ulteriori trasferimenti di memoria principale.
Se in alternativa, strutturiamo i loop in modo che l'indice di colonna vari nel ciclo più interno, si accederà alle voci di A nell'ordine A (1,1), A (1,2), A (1,3 ), ... In questo caso, il primo accesso porterebbe A (1,1), A (2,1), ..., A (8,1) nella cache dalla memoria principale, ma 7/8 di queste voci non sarebbero state utilizzate. L'accesso ad A (1,2) nella seconda iterazione porterebbe quindi ulteriori 8 voci dalla memoria principale e così via. Quando il codice inizia a funzionare sulla riga 2 della matrice, la voce A (2,1) potrebbe essere eliminata dalla cache per lasciare spazio ad altri dati necessari. Di conseguenza, il codice sta generando 8 volte il traffico necessario.
Alcuni compilatori ottimizzati sono in grado di ristrutturare automaticamente i loop per evitare questo problema.
Molti algoritmi di algebra lineare numerica per la moltiplicazione e la fattorizzazione delle matrici possono essere ottimizzati per funzionare in modo efficiente con lo schema di ordinamento riga maggiore o colonna maggiore in base al linguaggio di programmazione. In questo modo nel modo sbagliato può avere un impatto negativo significativo sulle prestazioni.
Fori loop sono molto lenti in MATLAB. Dovresti evitare cicli espliciti in MATLAB quando possibile. Invece, di solito un problema può essere espresso in termini di operazioni matrice / vettoriale. Questo è il modo MATLABic. Ci sono anche molte funzioni integrate per inizializzare le matrici, ecc. Ad esempio, esiste una funzione, ones () , che imposta tutti gli elementi di una matrice su 1 (per estensione, su qualsiasi valore per moltiplicazione (uno scalare moltiplicato per la matrice di tutti)). Funziona anche su array 3D (che a mio avviso copre l'esempio qui).