Il est probable qu'il s'agisse d'un comportement de cache de l'UC (à 12 Mo, vos images dépassent de loin le cache L2 de 256 Ko de l'ARM Cortex A8 qui se trouve dans un iphone3gs).
Le premier exemple accède au tableau de lecture dans un ordre séquentiel, qui est rapide, mais doit accéder au tableau d'écriture dans le désordre, ce qui est lent.
Le deuxième exemple est le contraire: le tableau d'écriture est écrit dans un ordre séquentiel rapide et le tableau de lecture est accédé plus lentement. Les échecs d'écriture sont évidemment moins coûteux sous cette charge de travail que les échecs de lecture.
L'article d'Ulrich Drepper What Every Programmer Should Know About Memory est recommandé de lire si vous voulez en savoir plus sur ce genre de chose.
Notez que si vous avez cette opération enveloppé dans une fonction, alors vous aider à l'optimisateur pour générer un meilleur code si vous utilisez le qualificatif restrict
sur vos arguments pointeur, comme ceci:
void reorder(uint32_t restrict *buffer1, uint32_t restrict *buffer2)
{
int i = 0;
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
buffer1[x+y*width] = buffer2[i++];
}
(Le restrict
qualificateur promet au compilateur que les données pointées par les deux pointeurs ne se chevauchent pas - ce qui dans ce cas est nécessaire pour que la fonction ait du sens quand même).
Sauter entre différentes pages de mémoire? L'accès à la mémoire n'est pas une opération à temps constant, contrairement à ce que vous supposez dans la classe des algorithmes, bien que vous puissiez probablement lui imposer une limite supérieure pour une architecture donnée. –
Quelques questions: D'abord, testez-vous sur une version de débogage ou de version. Deuxièmement, comment déterminez-vous le moment? – Toji
Quelle est la sortie de l'assembly pour le segment de code? Cela ressemble à une absurdité d'architecture, à moins que je ne manque quelque chose d'évident. –