Kochise
:Pollux :Où ça ? Où ça j'insulte ? J'emet juste de 'profondes' réserves vis-à-vis des 'extraordinaires' performances du cache, y'a rien de répréhensible à cela :/
tu racontes des conneries en insultant les autres
Oué, euh, excuse-moi mais c pas vraiment profond ce que tu racontes

Et puis si "En clair et en français dans le texte", "Va jouer chez les amateurs de spec" et "Allez, un peu d'infos pour pas pleurer idiot" c'est pas me prendre pour un con (alors que tes posts sont ridicules de la tête aux pieds), je me demande ce que c'est

Regarde la démonstration par l'absurde :

Pollux :Puis :
on est pas du tout dans les facteurs 10 de cache vs pas cache
Je dis facteur 10 parce que c l'ordre de grandeur, mais effectivement je ne m'étais pas trop trompé...
Pollux
: Avec 200ko de mémoire allouée, ça prend 6.75 secondes ; en en faisant tourner 3 simultanément, ça prend exactement le même temps (tiens tiens) ; et en en faisant tourner un seul avec 3x plus de mémoire (donc ça ne tient plus du tout dans le cache) ça prend quasiment 3 minutes
Exact dans un sens, 22 fois plus rapide exactement (d'après ton test, attend la suite).
Bien, au moins tu sais compter ^^ (mais cf plus bas, sur mon ordinateur [pas celui de mes parents] le dual channel et la fréquence supérieure du bus font qu'il n'y a qu'un facteur 11).
Mais je doute fort que tous les processus s'amusent à réserver directement sur la pile avec alloca
, mais plutôt avec malloc, voire avec new (quoique j'ai pas vu de difference avec Visual C, alloca et malloc, mëme combat).

Tu crois que le processeur fait la moindre différence entre la pile et le tas ? Les différences ne se situent qu'au niveau de la gestion qu'en fait l'OS... Au niveau de la localité en cache, la seule chose qui pourrait changer, ce serait la contiguïté des données allouées si on fait plusieurs allocations, mais ici ce n'est pas pertinent puisqu'on alloue un seul gros bloc.
Ton exemple est vicieux vu qu'il consiste à faire 100000 'simple' écritures sur la taille d'un tableau (taille passée en paramètre). Or dans un cadre d'utilisation 'normale' (c'est à dire pas juste avec des routines simples pour faire cracher les chiffres), y'a le processeur qui s'en mèle pour faire des calculs savants
Bon, je vais souligner un point où tu n'as pas entièrement tort : faire un bench de mémoire, ça ne veut pas forcément dire faire un bench réaliste. Ce qui veut dire qu'effectivement, si on fait juste un calcul qui n'a pas besoin de bande passante mémoire, le cache n'apportera rien. De même qu'un bus mémoire avec une fréquence supérieure n'apporterait rien dans ce cas-là. Mais il se trouve que, précisément, les applications ont besoin à la fois de puissance de calcul et de bande passante mémoire

(et, puisque tu es un "spécialiste" des 68k et 486, je pense que tu n'es pas sans savoir que la bande passante vers la mémoire principale a augmenté bcp moins vite que la puissance de calcul, d'où la nécessité de caches -- d'ailleurs on peut voir la RAM comme la première forme de cache)
des branchements divers (qui eux invalident le prefetch), etc...
Euh ?

Bon allez je suis grand prince, je te fais un supermegabench pour te montrer que tous tes points sont faux :
~/bench-2004-07-11 $ cat cache-bench.c#include <stdio.h> int main(int argc,char **argv) { char *s=argv[1]; int n=atoi(s)/sizeof(int); int *p=alloca(n*sizeof(int)); int i,j,k; char rnd[32]; for (i=0;i<32;i++) rnd[i]=(rand()%217)&1; for (i=0;i<30000;i++) { for (j=0;j<n;/* slap les smileys qui apparaissent dans le code :| */) for (k=0;k<32;k++,j++) if (rnd[k]) p[j]+=i; asm volatile(""::"g"(p)); } }
~/bench-2004-07-11 $ gcc -O2 cache-bench.c -o cache-bench
~/bench-2004-07-11 $ time ./cache-bench.exe 400000
./cache-bench.exe 400000 10.53s user 0.01s system 99% cpu 10.571 total
~/bench-2004-07-11 $ time (./cache-bench.exe 400000|./cache-bench.exe 400000|./cache-bench.exe 400000)
(; ./cache-bench.exe 400000 | ./cache-bench.exe 400000 | ./cache-bench.exe ; ) 10.31s user 0.01s system 33% cpu 31.141 total
~/bench-2004-07-11 $ time ./cache-bench.exe 1200000
./cache-bench.exe 1200000 59.00s user 0.00s system 97% cpu 1:00.61 total
(j'ai pris des tailles 2x plus grandes parce que là je suis sur un Barton avec 512ko de cache)
Comme tu peux le constater, il y a :
* des lectures
* des écritures
* des calculs
* des branchements totalement imprédictibles (car aléatoires) à chaque itération
Et en plus une bonne partie du coût (test de rnd[k] et incrémentation) ne dépend pas du fait que le tableau "p" réside en cache ou non. (et accessoirement, on accède au tableau "p" 2x moins souvent que dans l'exemple d'avant)
Et pourtant, on remarque un facteur 6x de différence ! (contre 11x si on ne rajoute pas les branchements imprédictibles)
Note que les branchements sont effectivement imprédictibles, il y a une différence de 1.5 secondes si j'affecte des constantes (tjs 0 ou tjs 1) à rnd[k]... (et ce n'est pas une optimisation du compilo)
Mon processeur, un Athlon 1700+ (L1 core et data de 64 Ko, L2 de 256 Ko, même caractéristiques que ton 2600+), donne les résultats suivant avec ton code avec comme paramètre :
40000 -> 7 secondes
80000 -> 15 secondes (sortie du cache L1 de 65536 octets)
160000 -> 30 secondes
320000 -> 70 secondes (sortie du cache L2 de 262144 octets)
480000 -> 152 secondes
Je ne suis pas allé à 600000, vu que ce n'était pas la peine !
L'absence de différence L1-L2 est probablement normal, à cause de l'overhead de la boucle.
Et note que ton cache L2 est exclusif, donc la sortie du cache L2 se fait à 320ko... Tu peux peut-être essayer un peu plus loin, mais ça m'étonne que tu ne trouves qu'un facteur 1.7 entre L2 et RAM

Ce n'est donc MEME PAS 2 fois plus rapide, alors je ne comprend pas ton résultat de 22 fois (154.7/6.73) :/ Cette différence de 68% je l'obtient aussi sur mon 68030 (71% dans son cas) avec deux caches de 256 octets (on ne rit pas dans la salle, SVP) !
Moué, uploade ton binaire sur yN pour voir... (lien Upload à côté du formulaire de post)
Dans l'exemple de PhotoShop, si tu ne veux pas entendre parler de la taille des routines executées par le processeur (ce qui concerne en fait le cache d'instruction) mais plutôt les données traitées (comme dans ton exemple), tu ne fais à peine tenir dans les 256 Ko de ton cache de donnée qu'une image de 320*240 en 24 bits.
Sauf que les algos sont précisément conçus pour avoir une bonne localité en cache, i.e. faire 42 passes sur chaque pixel (et ceux aux alentours) plutôt que faire 42 passes sur toute l'image...
Pas très très représentatif des résolutions de la mort des cartes 3D actuelles, plutôt genre 1280*1024 (2.5 Mo en 16 bits, le double en 32 bits).
N'importe quoi. On peut avoir une bonne localité en cache même en 3d (et j'en sais qqch

Je suis d'accord en ce qui concerne les perfs de l'IWRAM de la GBA, vu la taille de l'écran et donc la mémoire à traiter, mais ce n'est pas aussi recevable en ce qui concerne les PC. Eux, ce qui peu allègrement les booster, ce serait une utilisation plus massive des instructions SIMD (qui peuvent elles accélérer jusqu'à 8 foix le calcul), trop régulièrement snobées par les codeux. En s'accroche trop souvent au cache ou à la FSB... Quoique ça aide (à hauteur de 68% donc)
Connais pas.
(mais *moi* je vais pas m'exprimer sur qqch que je connais pas

Pour te faire penser à ce que je viens de te dire, dis toi 'simplement' que l'un des composant essentiel du noyau de Windows, kernel32.dll, fait 'juste' 972 Ko. Bien sûr, il n'est pas chargé en entier dans le cache, juste les parties executées régulièrement. Mais kernel32.dll est loin d'être le seul composant appelé, y'a aussi gdi32.dll, 251 Ko !

cf les posts ci-dessus
D'ailleurs au fait, si on avait voulu optimiser un poil avec une vieille ruse d'apache, un 'for (i=100000-1;i>0;i--)' puis un 'for (j=n-1;j>0;j--)' auraient étés plus judicieux (pas de chargement de valeur, juste une comparaison avec 0). Mais bizarrement, c'est 45% plus lent sur un Athlon =:/ Va comprendre...
L'optimisation x86 moderne et l'optimisation 68k, c pas vraiment pareil...
Et désolé de briser ton rève et de jouer un peu le garde-fou.


