bonjour,
tout est dans la question.
Cordialement.
-----
bonjour,
tout est dans la question.
Cordialement.
J'imagine que tu fais référence aux paramètres que tu peux passer à un compilateur.
Un paramètre d'optimisation est une option permettant au compilteur de "modifier" le code pour que sont exécution soit plus rapide et/ou que sa taille prenne moins de place. C'est possible en ré-arangeant les accès a des variables (pour éviter les accès multiples à la mémoire), simplifiant certaine opération sur les nombres flottant (au détrimant de la précision), utilisant des fonctions matérielles d'un processeur spécifique...
Bonjour,lou_ibmix_xi
Re : qu'est-ce qu'un flag d'optimisation ?
J'imagine que tu fais référence aux paramètres que tu peux passer à un compilateur.
Un paramètre d'optimisation est une option permettant au compilteur de "modifier" le code pour que sont exécution soit plus rapide et/ou que sa taille prenne moins de place. C'est possible en ré-arangeant les accès a des variables (pour éviter les accès multiples à la mémoire), simplifiant certaine opération sur les nombres flottant (au détrimant de la précision), utilisant des fonctions matérielles d'un processeur spécifique...
sans vouloir paraphraser je vais reformuler ce que j'ai compris.
Donc un flag d'optimisation est une option que l'on définit au moment de compiler et qui va permettre au compilateur de modifier "mon_code.c" pour qu'à l'execution ca aille plus vite.
Tu aurais un exemple d'utilisation de cs paramètres?
Par exemple si je te montre un code en C à quel moment et comment je peux utiliser un flag d'optimisation?
je compile avec gcc -DTYPE_FLOAT main.cCode:#include <malloc.h> #include<stdio.h> #include<stdlib.h> #include<time.h> #include <sys/time.h> //permet de mesurer le temps passe dans les fonctions #include <string.h> // gcc -DTYPE_INT #ifdef TYPE_INT typedef int T; #else #ifdef TYPE_FLOAT typedef float T; #else #error "Need to give MACRO definition for element type : -DTYPE_INT or -DTYPE_FLOAT" #endif #endif //prototype fonction inline double deltaT(struct timeval debt, struct timeval finT);//calcul le tps pris entre 2 lectures de gettimeofday() void GEMV(T **A,T *u,T *v, int dim1, int dim2, char* forme);//produit matrice_dense/vecteur void SPMV(int **Indice,T *Values,T *u,T *v,int dim,char* forme);// produit matrice_creuse/vecteur //programme principal int main(int argc, char *argv[]) { //declarations parametres int dim1=atoi(argv[1]);// on precisera la taille des matrice en ligne de commande int dim2=atoi(argv[2]);// deuxieme argument donne en ligne de commande int i,j; T **A; T* u; T* resultat; //pour le stockage classique des matrices creuses int **I; //tableau d'indices T* Values; //tableau de valeurs non nuls de la matrice //Allocation dynamique Matrice Indice et vecteur Value equivalent a la matrice unite I =(int**) malloc(dim1*sizeof(*I)); Values=malloc(dim1*sizeof(T)); for(i=0;i<dim1;i++) { I[i]=(int*)malloc(2*sizeof(**I)); Values[i]=(T)1; I[i][0]=i; I[i][1]=i; } //pour le stockage de matrice dense //allocation dynamique en memoire de A, u et du vecteur resultat, prenons A=Identite A =(T**) malloc(dim1*sizeof(*A)); u=malloc(dim2*sizeof(T)); resultat=malloc(dim1*sizeof(T)); for(i=0;i<dim1;i++) { A[i]=(T*)malloc(dim2*sizeof(**A)); for(j=0;j<dim2;j++) { A[i][j]=(T)0; u[j]=(T)j; } A[i][i]=(T)1; } ////------------------------Affichage matrice ////affichons la matrice I et le tableau de valeurs //for (i=0;i<dim1;i++) //{ //for (j=0;j<2;j++) //{ //printf("%d\t", I[i][j]); //} //printf("|%f\n",Value[i] ); //} //printf("\n"); ////affichons la matrice A //for (i=0;i<dim1;i++) //{ //for (j=0;j<dim2;j++) //{ //printf("%f\t", A[i][j]); //} //printf("|%f\n",u[i] ); //} //printf("\n" ); //appel fonctions produit GEMV(A,u,resultat,dim1,dim2,argv[3]); //for(i=0;i<dim1;i++) // {printf("Avec GEMV v[%d]=%f\n",i,resultat[i]);} //on affiche le vecteur resultat //printf("on passe a creuse_classique\n"); //printf("\n"); SPMV(I,Values,u,resultat,dim2,argv[3]); //for(i=0;i<dim1;i++) // {printf("Avec SPMV v[%d]=%f\n",i,resultat[i]);} //on affiche le vecteur resultat //liberation en memoire de A et u for(i=0;i<dim1;i++) {free(A[i]);} free(A); free(u); //liberation en memoire de I for(i=0;i<dim1;i++) {free(I[i]);} free(I); return 0; } //calcul le tps pris entre 2 lecture de gettimeofday() inline double deltaT(struct timeval debT, struct timeval finT) { return finT.tv_sec - debT.tv_sec + (finT.tv_usec - debT.tv_usec)/1.E6; } //fonction produit matrice dense void GEMV(T **A,T *u,T *v, int dim1, int dim2, char* forme) { //parametres chronometre struct timeval debT, finT; //int compteur=0; int f_compteur=1; double temps_moy=0.0; //temps moyen //declaration parametres int i,k; //for(compteur=0;compteur<f_compteur;compteur++) //{ //top chrono gettimeofday(&debT,NULL); //calcul produit for (i=0;i<dim1;i++) {v[i]=(T)0;} for(i=0;i<dim1;i++) { for (k=0;k<dim2;k++) { v[i]=v[i]+A[i][k]*u[k]; } // printf("v[%d]=%d\n",i,v[i]); //on affiche le vecteur resultat } //stop chrono gettimeofday(&finT,NULL); temps_moy=temps_moy+deltaT(debT,finT); //} temps_moy = temps_moy/((double)f_compteur); //printf("le temps pris par la fonction GEMV est %f s\n",temps_moy); //lecture ecriture des resultats dans un fichier.cvs FILE* dense = NULL; dense = fopen("dense_C.csv", "a"); //ouverture du fichier en ecriture seule if(dense != NULL) { fprintf(dense,"%d; %d; %s; %f\n",dim1, dim2,forme,temps_moy); //fermeture du fichier fclose(dense); } } //fonction matrice creuse classique void SPMV(int **Indice,T *Values,T *u,T *v,int dim,char* forme) { //parametres chronometre //int compteur=0; int f_compteur=1; double temps_moy=0.0; //temps moyen struct timeval debT, finT; //declaration parametres int i,k,j,l; //for(compteur=0;compteur<f_compteur;compteur++) //{ // debut chrono gettimeofday(&debT,NULL); //calcul produit for(i=0;i<dim;i++) { v[i]=0;}//initialisation de v a 0 for(i=0;i<dim;i++) { v[Indice[i][0]]=v[Indice[i][0]]+Values[i]*u[Indice[i][1]]; // printf("v[%d]=%d\n",i,v[i]); } //fin chronometre gettimeofday(&finT,NULL); temps_moy=temps_moy+deltaT(debT,finT); //} temps_moy = temps_moy/((double)f_compteur); //printf("le temps pris par la fonction SPMV_classique est %f s\n",temps_moy); //lecture ecriture des resultats dans un fichier.cvs FILE* creuse_classique = NULL; creuse_classique = fopen("creuse_C.csv", "a"); //ouverture du fichier en ecriture seule if(creuse_classique != NULL) { fprintf(creuse_classique,"%d; %s; %f\n",dim,forme,temps_moy); //fermeture du fichier fclose(creuse_classique); } }
et j'exécute avec a.out 10 10 carree (par exemple)
Bonjour, pour gcc les flags d'optimisation sont (si mes souvenirs sont bons):
-O1: optimisation mineure
-O2: optimisation moyenne
-O3: optimisation maximale
Donc pour obtenir une optimisation maximale, il suffit dans votre cas de taper: gcc -DTYPE_FLOAT -O3 main.c
Je vois aussi dans votre code que vous employez des matrices. Un compilateur peut certe optimiser la vitesse d'un programme, mais le code écrit par le programmeur est critique, particulièrement quand il s'agit de matrices. Je vous conseille d'allouer la mémoire des vecteurs et matrices au moyen de fonctions données à la page 944 du document suivant: http://astronu.jinr.ru/wiki/upload/d...RecipesinC.pdf
C'est ce que j'emploie pour mes matrices et vecteur, et le code est environ 10x plus rapide que tout ce que j'ai pu écrire jusqu'à présent.
Faites également attention au fait que ces fonctions allouent les matrices suivant les lignes. Pour effectuer toute opération sur vos matrices la boucle la plus interne doit se faire sur les lignes et la plus externe sur les colonnes, sinon vous perdrez un facteur 2 à 5 de temps d'exécution dans votre programme.
ouiDonc un flag d'optimisation est une option que l'on définit au moment de compiler
non, il va générer un code machine différent à partir du même code source. Je pense que certaine optimisation doivent pouvoir se "voir" en arrếtant la compilation à la traduction du C vers le langage assembleur (option -S avec gcc)et qui va permettre au compilateur de modifier "mon_code.c"
Pas forcément, certaines optimisations peuvent se faire sur l'occupation mémoire, bien souvent au détriment de la vitesse d'exécution. C'est très utilisé pour les systèmes embarqués où la mémoire disponible est faible.pour qu'à l'execution ca aille plus vite.
Il te suffit d'appeler ton compilateur avec les bonnes options. Si tu utilises gcc, le plus courant est d'utiliser l'option -O suivi d'un niveau d'optimisation (de 0 à 3) où -Os pour optimiser en occupation mémoire. Tu peux également détailler les types d'optimisations mises-en-oeuvre / interdites, "man gcc" t'en diras plus.Tu aurais un exemple d'utilisation de cs paramètres?
Le "comment" est expliqué ci-dessus. Le "quand" dépends du programme et de son utilisation... Personnelement je n'utilise _JAMAIS_ d'optimisation pendant le développement d'une application, je mets éventuellement des optimisations au moemnt du déploiement d'une application lorsque la consommation d'énergie est critique (exécution + efficace -> moins de ressources processeur consummée -> moins d'énergie). Si c'est le cas, il faut vérifier que l'optimisation est effective (que le code optimisé tourne plus vite que sa version non optimisée) car ce n'est pas toujours le cas.Par exemple si je te montre un code en C à quel moment et comment je peux utiliser un flag d'optimisation?
Je ne dit pas que c'est la politique qu'il faut adopter forcément, d'autant plus que je suis dans l'informatique embarquée qui est très spécifique.
Bonjour, pour gcc les flags d'optimisation sont (si mes souvenirs sont bons):
-O1: optimisation mineure
-O2: optimisation moyenne
-O3: optimisation maximale
Donc pour obtenir une optimisation maximale, il suffit dans votre cas de taper: gcc -DTYPE_FLOAT -O3 main.c
Je vois aussi dans votre code que vous employez des matrices. Un compilateur peut certe optimiser la vitesse d'un programme, mais le code écrit par le programmeur est critique, particulièrement quand il s'agit de matrices. Je vous conseille d'allouer la mémoire des vecteurs et matrices au moyen de fonctions données à la page 944 du document suivant: http://astronu.jinr.ru/wiki/upload/d...RecipesinC.pdf
C'est ce que j'emploie pour mes matrices et vecteur, et le code est environ 10x plus rapide que tout ce que j'ai pu écrire jusqu'à présent.
Faites également attention au fait que ces fonctions allouent les matrices suivant les lignes. Pour effectuer toute opération sur vos matrices la boucle la plus interne doit se faire sur les lignes et la plus externe sur les colonnes, sinon vous perdrez un facteur 2 à 5 de temps d'exécution dans votre programme.
Bonjour,
Je voulais tester tes fonction mais je ne vois pas trops à qoi correspond ce qui est passé en argument :
par exemple pour allouer une matrice de double :
double **dmatrix(long nrl, long nrh, long ncl, long nch)
qu'est-ce que nrl, nrh, ncl, et nch ?
cordialement.
nrl: numéro de début de ligne
nrh: numéro de fin de ligne
ncl: numéro de début de colonne
nrh: numéro de fin de colonne
Exemple pour créer une matrice 5x6 avec les lignes numérotée de 1 à 5 et les colonnes de 1 à 6:
double **M;
M = dmatrix(1, 5, 1, 6);
Vous accédez ensuite à la matrice M comme vous le faites d'habitude: M[i][j] pour obtenir/modifier l'entrée (i, j).
Autre exemple: matrice 5x6 avec les lignes numérotées de 0 à 4 et les colonnes de 0 à 5:
double **M2;
M2 = dmatrix(0, 4, 0, 5);
Dernière modification par Paraboloide_Hyperbolique ; 16/07/2012 à 16h38.
Sinon je voulais passer à un autre code mais je ne sais pas si il faut que j'ouvre une nouvelle discussion parce que là c'est déjà la deuxième.
C'est un petit problème je suis sure que ça se règle vite mais j'ai besoin d'un regard exterieur pour ca.
J'ai fait en C++ une classe MDense et elle posède une méthode GEMV qui calcul le produit matrice/vecteur.
J'aimerais récupéré le temps moyen de calcul pour cette opération.
J'ai donc introduit une compteur pour répété le calcul un certain nombre de fois (f_compteur fois), mais il me multiplie le résultat du produit matrice/vecteur par f_compteur.
Je suis sur que c'est un truc tout bête mais je vois pas comment régler le problème.
Je vous met ci-dessous le code de la fonction :
Code:/**************************************************************************** * Fonction: MDense<T>::GEMV() * Description: effectue le produit matrice vecteur * Paramètres: le vecteur multiplié u, le vecteur resulat v, la forme de la matrice * Retour: aucun ****************************************************************************/ template <typename T> void MDense<T>::GEMV(const vector <T>& u, vector <T> v,char* forme) { //parametres chronometre int f_compteur=1; double temps_moy=0.0000; //temps moyen for(int compteur=0;compteur<f_compteur;compteur++) { //debut chrono timer t; t.elapsed(); for(int i=0; i< lignes_; i++) { for (int k=0; k<colonnes_; k++) { v[i]=donnees_[i][k]*u[k]+v[i]; } //cout<<"pour dense : v["<<i<<"]="<<v[i]<<endl; //fin chrono temps_moy=temps_moy+t.elapsed(); } } temps_moy = temps_moy/((double)f_compteur); // ouverture fichier en ecriture seule ofstream fichier("dense_cpp.csv", ios::out | ios::app); if(fichier) { fichier << lignes_ << ";" << colonnes_ << ";" << forme << ";" << temps_moy << endl; fichier.close(); } }
Bonsoir,
Il faudrait peut être travailler sur une copie de "v" dans votre boucle, puis recopier le résultat dans v à la fin.
Au passage, on est d'accord, cette partie du code est temporaire n'est ce pas ?
A+,
PS : c'est volontaire de ne pas utiliser les opérateurs raccourcis +=, /=, etc. ?
Bonjour,
Quel partie du code serait temporaire?
en fait je veux enregistrer pour chaque incrementation du compteur, un temps moyen de calcul de tous les v[i].
Si je fais uen copie du vecteur v[i] je la fait à quel moment? au sortir de la boucle sur les k? mais la copie serait toujours dans la boucle compteur nan?
Cordialement.