Bonjour à tous, je vous propose un petit challenge de programmation la plus efficace possible,
le but est de partager ses connaissances et montrer à tous des méthodes de programmation performantes
la règle du jeux est la suivante, à partir d'un code simple de filtrage d'image par exemple, tout candidat peut proposer ses propres modifications
et montrer à tous le gain en performance qu'il a pu noter. présentez les gains de vitesse chiffrés et proposez un code clair (et commenté) pour que chacun puisse le comprendre aisément.
Sont autorisés tout changement du code d'origine qui ne modifie pas le résultat final, à partir de là, toute optimisation est possible
pointeurs/registres, fonction intrinsics (SSE2 etc), threads etc tout est envisageable, mais doit rester portable (linux et windows, restons en là)
les shaders peuvent aussi être proposés.
Le code simple de base est présenté ci dessous, Bon courage à tous.
l'exemple proposé ici réalise un filtrage sur une image en NIVEAUX DE GRIS (donc, pas en RGB ou autre, juste sur un calque), ligne par ligne, de la gauche vers la droite, il s'agit en fait d'un filtrage passe bas (lissage des contours) assymétrique couramment utilisé en traitement d'image.
dans le code proposé, les calculs sont effectués sur une image de taille _NBrows par _NBcolumns
le résultat final est stocké dans le tableau 'outputFrame', en entrée on a le tableau outputFrame (résultat de la frame précédente par exemple que l'on va écraser après calcul), l'image d'entrée 'inputFrame' (de même taille que la sortie) et une autre image de paramètres 'window' de même taille que l'image de sortie), une variable temporaire 'value' permet d'inclure dans le calcul du pixel courant, le résultat du calcul du pixel précédent.
TOUS LES CALCULS SONT EFFECTUES EN TYPE DOUBLE
voici le code non optimisé :
%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 #include <iostream.h> #include <time.h> unsigned int _NBcolumns=640; // nombre de colonnes des buffers unsigned int _NBrows=480; // nombre de lignes des buffers // Entry point int main(int argc, char *argv[]) { // buffers d'entrée et de sortie double outputFrame[480][640], inputFrame[480][640], windowfilter[480][640]; // variables/buffers utilisés dans les boucles: double value, tau=10.0; unsigned int IDrow, IDcolumn, NBloops=100; cout<<"loop started"<<endl; int startTime=clock(); //appel de la fonction de filtrage 10 fois for (unsigned int i=0; i<NBloops; ++i) // def des variables de taille des buffers { /* PARTIE A OPTIMISER */ // boucle appelée pour toute nouvelle image d'entrée (inputFrame) on retyrouve le code suivant : for (IDrow=0; IDrow <_NBrows; ++IDrow) { value=0; // initialize la variable pour chaque nouvelle ligne traitée for (IDcolumn=0; IDcolumn<_NBcolumns ; ++IDcolumn) { value = outputFrame[IDrow][IDcolumn]*tau + inputFrame[IDrow][IDcolumn] + windowfilter[IDrow][IDcolumn]* value; outputFrame[IDrow][IDcolumn] = value; } } /* FIN DE LA PARTIE A OPTIMISER */ } int endTime=clock(); cout<<"filtering finished, time elapsed="<<(endTime-startTime)/(NBloops)<<"clocks"<<endl; return 0; }
merci pour vos contributions, pour toute les personnes intéressés par l'optimisation de code et les novices désireux de progresser (moi compris)
++
ALex :![]()
Partager