Ho scritto un programma piccolo, in cui ho dovuto usare il sistema di coordinate a bordo (x/y in array 2d) e stavo pensando se dovessi usare l'indicizzazione come array[x][y]
, che mi sembra più naturale o array[y][x]
che corrisponderebbe meglio il modo in cui la matrice è rappresentata in memoria. Credo che entrambi questi metodi funzioneranno se sono coerente e si tratta solo di problemi di denominazione, ma che dire delle convenzioni quando si scrivono programmi più grandi?Qual è la convenzione per l'indicizzazione di array 2D con coordinate x/y in C?
risposta
Nel mio campo (manipolazione delle immagini) la convenzione [y][x]
è più comune. Qualunque cosa tu faccia, sii coerente e documentala bene.
Si dovrebbe anche considerare che cosa si intende fare con questi array e se questo è fondamentale per il tempo.
Come menzionato nei commenti: L'elemento a[r][c+1]
è proprio accanto a a[r][c]
. Questo fatto potrebbe avere un impatto considerevole sulle prestazioni durante l'iterazione su array più grandi. Un corretto ordine trasversale farà sì che le linee della cache siano completamente sfruttate: quando si accede a un indice di array, si ritiene che sia "probabile" che in seguito si accederà all'indice successivo e verrà caricato un intero blocco di memoria nel cache. Se successivamente si accede a una posizione di memoria completamente diversa (ovvero, una nella riga successiva), questa larghezza di banda della cache viene sprecata.
Se possibile, provare a utilizzare un ordine di attraversamento che si adatti al layout di memoria effettivo.
(Naturalmente, questo è molto di "convenzioni" e "abitudini": Quando si scrive un accesso matrice come a[row][col]
, questo viene generalmente interpretato come accesso matrice a[y][x]
, grazie alla convenzione del x-asse essendo orizzontale e l'asse y essendo verticale ...)
Ecco un piccolo esempio che dimostra il potenziale impatto sulle prestazioni di un "sbagliato" ordine di attraversamento:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
float computeSumRowMajor(float **array, int rows, int cols)
{
float sum = 0;
for (int r=0; r<rows; r++)
{
for (int c=0; c<cols; c++)
{
sum += array[r][c];
}
}
return sum;
}
float computeSumColMajor(float **array, int rows, int cols)
{
float sum = 0;
for (int c=0; c<cols; c++)
{
for (int r=0; r<rows; r++)
{
sum += array[r][c];
}
}
return sum;
}
int main()
{
int rows = 5000;
int cols = 5000;
float **array = (float**)malloc(rows*sizeof(float*));
for (int r=0; r<rows; r++)
{
array[r] = (float*)malloc(cols*sizeof(float));
for (int c=0; c<cols; c++)
{
array[r][c] = 0.01f;
}
}
clock_t start, end;
start = clock();
float sumRowMajor = 0;
for (int i=0; i<10; i++)
{
sumRowMajor += computeSumRowMajor(array, rows, cols);
}
end = clock();
double timeRowMajor = ((double) (end - start))/CLOCKS_PER_SEC;
start = clock();
float sumColMajor = 0;
for (int i=0; i<10; i++)
{
sumColMajor += computeSumColMajor(array, rows, cols);
}
end = clock();
double timeColMajor = ((double) (end - start))/CLOCKS_PER_SEC;
printf("Row major %f, result %f\n", timeRowMajor, sumRowMajor);
printf("Col major %f, result %f\n", timeColMajor, sumColMajor);
return 0;
}
(scuse se ho violato alcune best practice qui, io sono usua un ragazzo Java ...)
Per me, l'accesso alla riga principale è quasi un ordine di grandezza più veloce dell'accesso alla colonna principale. Naturalmente, i numeri esatti saranno pesantemente dipendono dal sistema di destinazione, ma il problema generale dovrebbe essere lo stesso su tutti i target.
- 1. Convert lat lungo da coordinate XY C++
- 2. Converti aereo dato da xyz a coordinate xy in R (3D a 2D)
- 3. Crea array 2D Numpy dalle coordinate
- 4. perché la conversione di una lunga lista 2D in array numpy è così lenta?
- 5. Stampa di un array 2D in C
- 6. Qual è la convenzione standard per la creazione di un nuovo NSArray da un NSArray esistente?
- 7. 2d array di zeri
- 8. Qual è la convenzione per l'estensione del nome file Lisp?
- 9. Accesso a un array 1D come array 2D in C++
- 10. con array 2D
- 11. Array di grandi dimensioni e frammentazione LOH. Qual è la convenzione accettata?
- 12. due array che definiscono le coordinate 2D, come indici di array, in MATLAB/OTTAVE
- 13. Qual è la normale convenzione per nominare e usare gli iteratori in C++?
- 14. Come allocare un array 2D di puntatori in C++
- 15. Overflow di stack di Visual Studio C++ con array 2D
- 16. memoria dinamica per array 2D 2D
- 17. Puntatori a 2D array C, C++
- 18. Qual è il modo più veloce per calcolare la distribuzione di frequenza per array in C#?
- 19. Algoritmo dijkstra per array 2D in Java
- 20. Standardizzare 2D/3D Vector/coordinate Class
- 21. invio di blocchi di array 2D in C utilizzando MPI
- 22. Convenzione di nomi per l'eliminazione dei dati in C++
- 23. Qual è la convenzione per il prefisso di categorie con parole magiche?
- 24. Qual è la convenzione di denominazione ottimale per i file di test in Python?
- 25. Recupera il punto centrale Coordinate XY dalla selezione
- 26. Come dividere la stringa in array 2D con Regex?
- 27. Array 2D in Kotlin
- 28. Looping attraverso una formula che descrive una spirale per generare le coordinate XY
- 29. Slice array 2d in array 2d più piccoli
- 30. Qual è la convenzione di chiamata predefinita di una funzione lambda C++?
Fintanto che sei coerente non dovrebbe essere importante, ma ci sono due casi in cui posso pensare a dove 'array [y] [x]' sarà d'aiuto. 1) Un array di stringhe, dove potresti voler elaborare l'array 1-d '[y]'. 2) Una matrice di immagini, in cui è possibile eseguire la scansione di una linea raster. Preferisco 'array [y] [x]' con cicli di elaborazione annidati 'for (y ...) per (x ...)'. –
Le matrici sono di riga maggiore, quindi 'a [0] [1]' è la posizione di memoria successiva dopo 'a [0] [0]'. Scegli quale strada sarà adatta al tuo programma. –
.language per naturale più è come '[y] [x]' Usa – chux