Maison >développement back-end >C++ >Pourquoi mon programme ralentit-il considérablement lors du traitement des éléments 8192 en raison de modèles d'accès à la mémoire ?
Dilemme de gestion de la mémoire dans un programme à exécution lente
Lorsqu'un programme itère sur un nombre spécifique d'éléments, en particulier 8192, il peut présenter un ralentissement notable. Ce phénomène découle de la gestion de la mémoire, un sujet complexe qui mérite une exploration plus approfondie.
Présentation du code
Considérez la boucle en question, qui effectue des opérations sur une matrice prédéfinie :
for (i = 1; i < SIZE - 1; i++) { for (j = 1; j < SIZE - 1; j++) { res[j][i] = 0; for (k = -1; k < 2; k++) for (l = -1; l < 2; l++) res[j][i] += img[j + l][i + k]; res[j][i] /= 9; } }
L'écart de performances du programme provient du type de disposition de la mémoire utilisée. Lors de l'accès aux baies, les processeurs modernes préfèrent les blocs de mémoire contigus pour une efficacité optimale. Cependant, lorsque les boucles parcourent des éléments de manière non linéaire, comme c'est le cas dans le code fourni, le processeur peut rencontrer des blocages de mémoire lorsqu'il tente d'accéder à des données non séquentielles.
Super- Problèmes d'alignement et de cache
Le nœud du problème réside dans le « super-alignement », un phénomène dans lequel le processeur préfère accéder aux blocs de mémoire qui sont multiples d'une taille particulière, souvent 16 ou 32 octets. Dans ce cas, la boucle externe parcourt les lignes, tandis que la boucle interne parcourt les colonnes. Lorsque SIZE est un multiple de 2048, la boucle externe ignore de grandes parties de mémoire entre les lignes, ce qui entraîne des retards dans le processeur pendant qu'il attend les données.
Comparaison des performances
Les temps d'exécution suivants démontrent l'impact sur les performances :
SIZE = 8191: 3.44 secs SIZE = 8192: 7.20 secs SIZE = 8193: 3.18 secs
Solution : Réorganisation Boucles
La solution à ce problème consiste à réorganiser les boucles de telle sorte que la boucle externe parcourt les colonnes au lieu des lignes. Cela garantit que le programme accède aux blocs de mémoire contigus, éliminant l'accès non séquentiel qui provoque le ralentissement.
La boucle modifiée :
for (j = 1; j < SIZE - 1; j++) { for (i = 1; i < SIZE - 1; i++) { ... (same operations as before) ... } }
En implémentant cette modification, la disparité de performances disparaît, comme le montrent les temps d'exécution suivants :
SIZE = 8191: 0.376 seconds SIZE = 8192: 0.357 seconds SIZE = 8193: 0.351 seconds
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!