Calcul sur une matrice, optimisation ? - C - Programmation
Marsh Posté le 12-10-2004 à 15:30:51
quand tu calcul la somme d'une colonne, pour respecter l'ordre de ton code, tu peux en profiter pour ajouter la valeur courante à la ligne correspondante.
=> une seule boucle au lieu de 2.
Marsh Posté le 12-10-2004 à 15:31:05
pour faire un peu plus rapide (mais surement encore optimisable, tu peux utiliser 2 iterateurs.
l'un commence au debut de ta ligne, l'autre a la fin (idem si c'est des colonne)
Et tu les fais aller, simultanément pour qu'ils se rejoingne a MAX/2
T'as plus qu'a additioner les 2 valeurs recupéré par tour de boucle.
Ya surement mieux, mais cette amélioration divise quand meme par deux le temps de calcul.
Marsh Posté le 12-10-2004 à 15:32:14
oui, un seul parcour suffit
un truc dans ce genre la
...
colsums[i] = 0;
rowsums[i] = 0;
for( j = 0; j < MAX; j++ )
{
colsums[i] += x[j][i];
rowsums[i] += x[i][j];
}
...
Marsh Posté le 12-10-2004 à 15:32:15
c0wb0y a écrit : pour faire un peu plus rapide (mais surement encore optimisable, tu peux utiliser 2 iterateurs. |
Non.
Marsh Posté le 12-10-2004 à 15:35:41
cris56 a écrit : oui, un seul parcour suffit |
Il y a du mieux, mais tu continues à faire 2 accès aléatoires pour chaque case visitée. Si tu fais:
rowsums[j] += x[j][i];
Ca a plus de gueule, car rowsums a plus de chance d'être en cache (il ne fait que 512 cases, contre 262144 pour la matrice x), et tu n'accèdes qu'une fois à chaque case de ta matrice (en fait, 2, mais le compilateur l'optimisera).
Marsh Posté le 12-10-2004 à 15:38:04
cris56 a écrit : oui, un seul parcour suffit |
euh la tu ferais bien de mesurer, tu risques de foutre en l'air ton cache (et si la matrice est grande, faire plein de défauts de pages). prudence donc
Marsh Posté le 12-10-2004 à 15:38:23
Code :
|
non ?
Marsh Posté le 12-10-2004 à 15:38:57
( hum, si mon erreur était par rapport au "temps de calcul divisé par deux" alors j'ai compris, j'ai dis n'importequoi en fait (: ya autant de calcul, c'est juste la longueur des parcours qui est réduite, m'enfin on doit y gagner un peu qd meme je pense )
Si c'était pas par rapport a ca, alors j'vois pas
Marsh Posté le 12-10-2004 à 15:39:44
Lam's a écrit : |
tout a fais, j'y avais meme pensé mais la je m'etais d'abord servi du fait que la matrice etais carré, si elle ne l'etais pas ta solution s'imposait d'elle meme
merci
edit : taz > oue, je viens de voir
Marsh Posté le 12-10-2004 à 15:40:27
c0wb0y a écrit : Si c'était pas par rapport a ca, alors j'vois pas |
Vi c'était ça. Mais tu peux aussi bien simplement dérouler ta boucle, sans avoir à passer par l'arrière...
Marsh Posté le 12-10-2004 à 15:49:03
( j'sais pas ce que ca veut dire derouler une boucle
C'est ca quand on se limite au poly de C qu'on a en cours :] )
Marsh Posté le 12-10-2004 à 15:55:05
loop unrolling en anglais. A mon avis, google a 2 ou 3 trucs à dire à ce propos
Marsh Posté le 12-10-2004 à 23:08:20
Merci les gas, justement cest pour nous aprendre a utiliser le cache, on doit tout dabord faire une methode la plus pourrie possible (je vais essayer de retoucher mon premier exemple), et une optimise le mieux que l on peut.
le cache :
64kB, 4-way set associative, with a 32-byte cache line
je vais esseyer plusieurs methode et poster les temps.
Marsh Posté le 12-10-2004 à 23:21:31
for(i=0;i<SIZE;i++) truc(i);
=>
for(i=0;i<SIZE/4;i++)
{
truc(4*i);
truc(4*i+1);
truc(4*i+2);
truc(4*i+3);
}
poru i < 300 a peu pres, vitesse x2 a x3 sur du Pentium, x4-5 sur du PPC
Marsh Posté le 12-10-2004 à 23:31:22
t'as déjà essayé avec les __builtins de prefetch de gcc ?
bah bah bah, faut pas faire comme ça, faut faire avec i < SIZE; i += 4; tu dois au moins sauver 2/3 instructions avec ça
Marsh Posté le 12-10-2004 à 23:34:32
Taz a écrit : |
bizzarement non :| et au moins avec ma version je ne me chie pas dednas ^^
Marsh Posté le 12-10-2004 à 23:44:26
je te parle de traiter les quelques éléments qui restent si SIZE % 4 != 0
avec gcc3.3 (et 3.4), j'ai un registre de plus utilisé pour stocker le i * 4
Marsh Posté le 12-10-2004 à 23:46:25
si SIZE%4 evidemment ^^
sous gcc 3.3 Apple j'ai pas ce registre en plus.
Marsh Posté le 12-10-2004 à 23:49:25
Code :
|
en gcc -O3 -S ça te donne quoi respectivement ?
Marsh Posté le 13-10-2004 à 01:13:29
la matrice est de [512*512] donc multiple de 4.
voila different methodes plus leur temps.
compiler avec cc -O
bi proc ultra sparc
methode du premier post : 8.29 ms
seconde methode
Code :
|
11,90 ms
Pour celle qui utilise le 4 way associative cache,
truc(i) est censez faire quoi ?
Marsh Posté le 13-10-2004 à 01:44:44
déjà si tu veux faire un benchmark, il faut que ton processus tourne au moins une minute et que tu prennes un temps moyen sur au moins 3 exécutions consécutives
Marsh Posté le 13-10-2004 à 02:08:38
j ai utilise le prog donne par le prof.
lequel servira amesurer nos algo.
Code :
|
8,77 ms
je comprend pas trop l exemple pour le 4 way cache assiociative, pouriez vous develope un peu ?
merci
Marsh Posté le 13-10-2004 à 09:19:00
fait des vrais mesures ! tu peux pas conclure sur des durées aussi ridicules.
Marsh Posté le 13-10-2004 à 09:33:30
Taz a écrit : |
-- truc effacé paske faux
Marsh Posté le 13-10-2004 à 09:50:17
Pour la version la plus lente possible, jacced au column et row de la matrice 8 par 8 (32 byte line, 4 way associative il load 8 word a chaque fois) pour avoir un maximum de miss.
grace a ca je tombe a 14.8 m/s, c est yune moyenne apres plusieurs test.
Taz tu peus aller verifier : http://www.comp.mq.edu.au/units/co [...] nts/3.html
J aimerai savoir si il existe es outils montrant le nombre de miss sur le cache ? de facon a savoir ou sa coince.
Pourais je avoir plus dexplication sur :
Code :
|
Marsh Posté le 13-10-2004 à 09:52:32
Code :
|
Code :
|
Marsh Posté le 13-10-2004 à 09:53:50
moi je veux savoir comment tu peux tirer des conclusions sur des laps de temps aussi ridicule ?
Marsh Posté le 13-10-2004 à 09:55:34
comme ca
Code :
|
Marsh Posté le 13-10-2004 à 09:59:04
xiluoc a écrit : |
53 km/h. C'est une vitesse raisonnable en ville. Pourquoi veux-tu aller plus vite ?
Tu as fais un google sur "loop unrolling" ou bien tu veux qu'on fasse le copier/coller pour toi ?
Et sinon, tu es sûr du copier/coller de la solution du prof ? Ca me parrait bizarre qu'il accède à la matrice colonne par colonne...
Marsh Posté le 13-10-2004 à 10:00:29
comment je t'ai bien eu Joelf, le gcc de MacOSX est pourri ! tu fais à chaque fois la multiplication ! alors que moi le calcul est factorisé ! (et je parle pas de tous les load pour recharger i à chaque fois)
ma version fait donc du code franchement meilleur ! et mon GCC rox !
Marsh Posté le 13-10-2004 à 10:09:45
Lam's a écrit : [...]Et sinon, tu es sûr du copier/coller de la solution du prof ? Ca me parrait bizarre qu'il accède à la matrice colonne par colonne... |
+1
et pis
Code :
|
hors de la boucle j ca me paraît louche.
Marsh Posté le 13-10-2004 à 10:18:59
Taz a écrit : comment je t'ai bien eu Joelf, le gcc de MacOSX est pourri ! tu fais à chaque fois la multiplication ! alors que moi le calcul est factorisé ! (et je parle pas de tous les load pour recharger i à chaque fois) |
han, na c'est moi qui est la plus grosse
hmmm 2sec ...
j'etais pas en -o3
ma version
Code :
|
Marsh Posté le 13-10-2004 à 10:24:05
ben peut etre que si ta fonction f etait pas vide, -O3 la laisserrai vivre
fiel moi exactement le code que tu utilise.
Marsh Posté le 13-10-2004 à 10:26:10
mon code :
Code :
|
la sortie assembleur en -O3 -mcpu=ppc-g5
Code :
|
Marsh Posté le 13-10-2004 à 10:28:04
ben je te l'ai filé !
c'est clair pourtant, il a pas le code de f ... et pourtant il vire les appels, mais il garde la boucle ... (alors que chez moi évidemment si void f(int i) { } g est alors vide ...
y a un truc qui foire terrible là ...
Marsh Posté le 13-10-2004 à 10:29:28
Joel F a écrit : mon code :
|
tu peux pas faire comme tout le monde ? si je te file du code, c'est justement pour qu'on compare ...
Marsh Posté le 12-10-2004 à 15:09:49
,
J ai une matrice de [512]*[512],
je dois calculer la somme de chaque colone et ligne de la matrice.
en sauvant le resultat de chaque operation dans colsums[n] ou rowsums[m].
Il y a t-il une methode/algo plus rapide que ce genre de chose
merci