Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2489 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Optimisation et multi-thread en C

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Optimisation et multi-thread en C

n°2127785
Mourfizbak
Posté le 22-02-2012 à 12:13:47  profilanswer
 

Bonjour à tous !
 
Je suis physicien (ça pose le niveau en C ^^) et j'utilise un programme en C pour faire de l'inférence statistique (méthode bootstrap) sur des images. Je travaille avec de gros fichiers binaires ( > 1Go).
Je dispose d'une puissance de calcul confortable (12 coeurs cadencés à 2,67GHz et 190 Go de RAM sous plate forme Unix (Ubuntu)), mais mon programme met un temps fou à s'exécuter (10min dans le cas simple, plusieurs jours dans les cas qui m'intéressent).  
 
En gros : Je génère 5 de ces fichiers binaires,ensuite j'en regénère 5 autres (sous images) à partir de ceux-la par des procédés de tirages aléatoires lignes par lignes avec remise (je stocke tout ça sur le HDD oO) et ensuite je somme ces 5 sous-images pixel par pixel pour me donner une image finale (toujours sous forme de fichier binaire). Je réitère ce procédé un certain nombre de fois suivant le nombre d'images finale dont j'ai besoin (a priori environ 250 !!!).
 
J'ai tenté d'ajouter des pragma ( #pragma omp parallel for ) avant les boucles qui génèrent les images. Dans le terminal je rentre :  
gcc -fopenmp fichier -o output
export OMP_NUM_THREAD=8  (j'ai essayé beaucoup de nombre de threads différents, mais mon temps d'exécution reste à peu près constant oO)
./output
 
Du coup, je ne sais plus trop quoi faire...J'imagine que ce qui prend le plus de temps est la copie des fichiers sur le disque dur (qui pour le coup n'est pas à accès rapide...il me faudrait un SSD en 100Go ^^), mais je ne vois pas comment faire autrement. Pour l'instant je créé mes sous-images, je génère mon image, je supprime les sous-images et je recommence...
Petite question naïve : est-il possible de copier les images intermédiaires sur la RAM (ce qui serait nettement plus efficient) ?
 
Merci d'avance pour votre aide !
 
Mouarfizbak

Message cité 1 fois
Message édité par Mourfizbak le 22-02-2012 à 12:15:18
mood
Publicité
Posté le 22-02-2012 à 12:13:47  profilanswer
 

n°2127789
in_your_ph​ion
Posté le 22-02-2012 à 12:52:11  profilanswer
 

Cela vient peut être de ton algorithme ..

 

Tu dois pouvoir stocker des données en RAM et écrire seulement à la fin. Mais ça dépend combien tu veux stocker.

 

Autrement, je te suggérerais de revoir ton algo et essayer déjà dans un premier temps de l'optimiser. Si ça se trouve, tu fais des copies inutiles dans tous les sens. Enfin, tu peux utiliser Valgrind et KcacheGrind qui te permettrons de faire un diagnostic précis pour voir où ton programme passe le plus clair de son temps et si tu peux modifier quelque chose.

 

http://kcachegrind.sourceforge.net [...] GrindIndex

 

sinon pour le multithread, ça dépend si tu peux paralléliser certaines taches ou pas ? d'autres membres du forum serons peut être plus expert que moi...


Message édité par in_your_phion le 22-02-2012 à 12:54:03
n°2127791
Mourfizbak
Posté le 22-02-2012 à 12:56:17  profilanswer
 

J'ai déjà tenté de limiter au maximum la quantité d'informations écrites ou supprimées sur le disque dur, mais il y a surement encore des choses à faire de ce côté. Je vais suivre ton conseil et continuer dans cette voie...
 
Merci pour ton lien !Je ne savais pas qu'il était possible d'obtenir ces informations là sur l'exécution du programme.
 
Concernant l'utilisation multi-coeurs, aurais-tu une idée ?Pour l'instant, malgré tous mes efforts j'ai un coeur à 100%, deux autres qui oscillent entre 5% et 20% et tous les autres à 0%...Peut-être que le compilateur ne peut pas partager les tâches plus que cela ?

n°2127807
in_your_ph​ion
Posté le 22-02-2012 à 14:53:52  profilanswer
 

Mourfizbak a écrit :

J'ai déjà tenté de limiter au maximum la quantité d'informations écrites ou supprimées sur le disque dur, mais il y a surement encore des choses à faire de ce côté. Je vais suivre ton conseil et continuer dans cette voie...

 

tu as peut être des données que tu peux pré calculer ? ou charger au démarrage en mémoire plutôt que de faire des fread() dans tous les sens en cours d’exécution....

 
Mourfizbak a écrit :

Concernant l'utilisation multi-coeurs, aurais-tu une idée ?Pour l'instant, malgré tous mes efforts j'ai un coeur à 100%, deux autres qui oscillent entre 5% et 20% et tous les autres à 0%...Peut-être que le compilateur ne peut pas partager les tâches plus que cela ?

 

pour les threads, je suis pas spécialiste ... il me semble que dans l’idéal tu peux en affecter un à chaque cœur (donc idéalement autant de thread que de coeur)

 

un truc important est aussi de mettre correctement les affinités et la priorités des threads. Quels threads tu affectes à quel coeur, et quel priorité ils ont.

 

http://linux.die.net/man/2/sched_setaffinity
http://www.icir.org/gregor/tools/p [...] uling.html

 

enfin tu as des librairies du types intel thread building blocks qui sont bien je crois, si tu choisis de faire plusieurs threads
http://threadingbuildingblocks.org/


Message édité par in_your_phion le 22-02-2012 à 14:57:01
n°2127859
tpierron
Posté le 22-02-2012 à 20:14:49  profilanswer
 

Hmm, de ce que tu décris, il me semble que ton programme ne s'exécute que sur un seul CPU. J'éviterais de te conseiller de faire du multi-threading à la main, parce qu'en C, c'est assez casse-gueule, surtout si on ne connait pas trop le language.
 
Du temps où j'avais fait du openmp, il me semblait qu'il y avait des restrictions sur les boucles parallélisables. Si la boucle était trop complexe, le compilateur ne faisait rien. Bref, il ne suffisait pas de parsemer le code de #pragma omp parallel for avant chaque "for" pour tu aies un temps d'exécution réduit de façon linéaire.
 
Avec la quantité de RAM que tu as, j'essaierais aussi de faire un maximum de traitement en mémoire, parce que sinon, si tu fais trop d'entrées/sorties, ça risque de méchamment pénaliser les performances, d'autant que le multi-thread ne fera qu'empirer les choses. Regarde si le disque sature au moment où ton programme tourne.
 
Si le disque ne sature pas, alors avec N threads actif, ton programme doit occuper 100% d'utilisation de N CPU, sans être obligé de configurer quoi que ce soit. S'il y a moins de CPU actif, c'est très probablement parce qu'il y a moins de thread (là encore, sauf problème d'entrées/sorties).

n°2127897
Mourfizbak
Posté le 23-02-2012 à 09:09:23  profilanswer
 

tpierron a écrit :

Hmm, de ce que tu décris, il me semble que ton programme ne s'exécute que sur un seul CPU. J'éviterais de te conseiller de faire du multi-threading à la main, parce qu'en C, c'est assez casse-gueule, surtout si on ne connait pas trop le language.
 
Du temps où j'avais fait du openmp, il me semblait qu'il y avait des restrictions sur les boucles parallélisables. Si la boucle était trop complexe, le compilateur ne faisait rien. Bref, il ne suffisait pas de parsemer le code de #pragma omp parallel for avant chaque "for" pour tu aies un temps d'exécution réduit de façon linéaire.
 
Avec la quantité de RAM que tu as, j'essaierais aussi de faire un maximum de traitement en mémoire, parce que sinon, si tu fais trop d'entrées/sorties, ça risque de méchamment pénaliser les performances, d'autant que le multi-thread ne fera qu'empirer les choses. Regarde si le disque sature au moment où ton programme tourne.
 
Si le disque ne sature pas, alors avec N threads actif, ton programme doit occuper 100% d'utilisation de N CPU, sans être obligé de configurer quoi que ce soit. S'il y a moins de CPU actif, c'est très probablement parce qu'il y a moins de thread (là encore, sauf problème d'entrées/sorties).


 
Mince, j'avais espoir que cela suffise :-/
 
Qu'appelles-tu "entrées/sorties" ?Le fait de copier ou lire sur le disque dur ?
Concernant le traitement en mémoire, comment procéder ?A coup de malloc ?
 
J'ai essayé de farfouiller sur internet à la recherche d'infos, mais je pense que je n'utilise pas les bons mots clés...
 
Merci d'avance !

n°2127906
shaoyin
Posté le 23-02-2012 à 09:38:46  profilanswer
 

Si tu bosses sous Ubuntu, tu peux monter un répertoire en tmpfs et travailler dans ce répertoire pour tes écritures de fichiers. Concrètement, cela te permet de travailler sur une zone en RAM comme s'il s'agissait d'un répertoire, donc avec des lectures/écritures comme si tu manipulais des fichiers. L'avantage, c'est que cela ne devrait pas avoir beaucoup d'impact dans ton programme.
 
Il y a pas mal de tutoriels sur le web, et ce n'est pas très compliqué à mettre en oeuvre.
Allez, pour te faire gagner un peu de temps : va voir sur http://www.generation-linux.fr/ind [...] -stockage.

n°2127919
in_your_ph​ion
Posté le 23-02-2012 à 10:49:54  profilanswer
 

Mourfizbak a écrit :


Qu'appelles-tu "entrées/sorties" ?Le fait de copier ou lire sur le disque dur ?

 

D'une manière générale, les temps d'accès au disque dur sont trèèèès longs ... Il faut donc que tu évites à maximum de faire les lectures ou des écritures sur le disque. Par exemple, tu fais au début une lecture et tu stockes tout dans des "variables" de ton programme, donc en RAM qui est beaucoup plus rapide d'accès que les DD. A la fin de ton programme tu peux écrire des fichiers. Mais faire des lectures/écritures sur un disque dur sera pénalisant si c'est intensif et au coeur de ton algorithme.
Au niveau des temps d'accès c'est le cache le plus rapide, ensuite la RAM, puis très loin loin derrière le disque dur. Et encore plus loin le lecteur CD rom, etc.

 
Mourfizbak a écrit :


Concernant le traitement en mémoire, comment procéder ?A coup de malloc ?

 

tu peux aussi essayer de faire plutôt des allocations sur la pile que sur le tas. Ce sera toujours moins rapide de faire une allocation "dynamique" comme le nom l'indique que d'allouer une variable de manière automatique car tu incrémentes juste un pointeur dans ce cas. Tu peux également vérifier que tu passes les objets par pointeurs à tes fonctions et non pas par copie ... auquel cas c'est inutile et prendra "du temps".

 

Enfin tu dis que tu utilises des images, déclarer un tableau 1D est plus rapide au niveau des accès qu'un tableau 2D.

 
Code :
  1. int a[sy][sx];
  2. a[4][3];
 

est équivalent à

Code :
  1. int a[sy*sx];
  2. a[4*sx + 3];


Message cité 1 fois
Message édité par in_your_phion le 23-02-2012 à 11:01:33
n°2127936
Mourfizbak
Posté le 23-02-2012 à 11:21:52  profilanswer
 

shaoyin a écrit :

Si tu bosses sous Ubuntu, tu peux monter un répertoire en tmpfs et travailler dans ce répertoire pour tes écritures de fichiers. Concrètement, cela te permet de travailler sur une zone en RAM comme s'il s'agissait d'un répertoire, donc avec des lectures/écritures comme si tu manipulais des fichiers. L'avantage, c'est que cela ne devrait pas avoir beaucoup d'impact dans ton programme.
 
Il y a pas mal de tutoriels sur le web, et ce n'est pas très compliqué à mettre en oeuvre.
Allez, pour te faire gagner un peu de temps : va voir sur http://www.generation-linux.fr/ind [...] -stockage.


 
Je travaille maintenant sur le répertoire en tmpfs, mais je n'ai pas différence vraiment flagrante en temps d'exécution...Je suis vraiment limité par cette saleté de somme pixel par pixel de mes 5 images :-/
Mais je te remercie pour l'info, ça a quand même apporté une amélioration !
 

in_your_phion a écrit :


 
D'une manière générale, les temps d'accès au disque dur sont trèèèès longs ... Il faut donc que tu évites à maximum de faire les lectures ou des écritures sur le disque. Par exemple, tu fais au début une lecture et tu stockes tout dans des "variables" de ton programme, donc en RAM qui est beaucoup plus rapide d'accès que les DD. A la fin de ton programme tu peux écrire des fichiers. Mais faire des lectures/écritures sur un disque dur sera pénalisant si c'est intensif et au coeur de ton algorithme.
Au niveau des temps d'accès c'est le cache le plus rapide, ensuite la RAM, puis très loin loin derrière le disque dur. Et encore plus loin le lecteur CD rom, etc.
 
 
 
tu peux aussi essayer de faire plutôt des allocations sur la pile que sur le tas. Ce sera toujours moins rapide de faire une allocation "dynamique" comme le nom l'indique que d'allouer une variable de manière automatique car tu incrémentes juste un pointeur dans ce cas. Tu peux également vérifier que tu passes les objets par pointeurs à tes fonctions et non pas par copie ... auquel cas c'est inutile et prendra "du temps".
 
Enfin tu dis que tu utilises des images, déclarer un tableau 1D est plus rapide au niveau des accès qu'un tableau 2D.
 

Code :
  1. int a[sy][sx];
  2. a[4][3];


 
est équivalent à  

Code :
  1. int a[sy*sx];
  2. a[4*sx + 3];




 
En fait je travaille avec des images sous forme de fichiers binaires, que je conserve sous forme de fichiers binaires et que je traite via des fopen, fseek...
J'ai l'impression que le programme perd énormément de temps (>90% du temps d'exécution) à sommer pixel par pixel les 5 images (> 1 million de pixels quand même !), et pas moyen de faire du multi-coeur...
 
Je te remercie beaucoup pour ces précisions, je vais me pencher sur les allocations sur la pile...
Tu me parles de faire une lecture au début et de tout stocker dans des variables, mais est-ce que je peux stocker une image issue d'une opération de tirage avec remise ligne par ligne d''autres images dans une variable, sans rien écrire sur le disque (ou sur la RAM du coup, grâce à la méthode de Shaoyin ?Ce n'est pas dit...Mais je vais creuser le sujet !
 
Merci encore pour votre implication, ça se démêle petit à petit :-)

n°2127955
in_your_ph​ion
Posté le 23-02-2012 à 12:11:17  profilanswer
 

Mourfizbak a écrit :


En fait je travaille avec des images sous forme de fichiers binaires, que je conserve sous forme de fichiers binaires et que je traite via des fopen, fseek...

 

Bad idea, à mon avis.

 
Mourfizbak a écrit :


J'ai l'impression que le programme perd énormément de temps (>90% du temps d'exécution) à sommer pixel par pixel les 5 images (> 1 million de pixels quand même !), et pas moyen de faire du multi-coeur...

 

tu as un exemple de boucle ?

 
Mourfizbak a écrit :


est-ce que je peux stocker une image issue d'une opération de tirage avec remise ligne par ligne d''autres images dans une variable, sans rien écrire sur le disque

 

normalement oui, tu as juste à stocker les valeurs dans des variables pendant que ton programme s’exécute. Ce sera chargé en RAM. Tu es limité à 2Go de mémoire par processus si tu es sur un processeur 32 bits.


Message édité par in_your_phion le 23-02-2012 à 12:11:31
mood
Publicité
Posté le 23-02-2012 à 12:11:17  profilanswer
 

n°2127965
Mourfizbak
Posté le 23-02-2012 à 12:29:17  profilanswer
 

Erf...Bon, sinon je peux copier les données des fichiers binaires dans des tableaux 2D et reconstituer les fichiers binaires à partir de tableaux 2D après traitement...?
 
Voilà le bout de code qui ouvre les 5 sous-images (subsino1 -> subsino 5), puis qui les somme pixel par pixel...C'est sur ce bout (plus exactement sur le while je crois) que le programme passe un temps fou oO
J'espère que ce n'est pas trop crado à lire :-/
 

Code :
  1. int main(){
  2. char nom[20] ;
  3. char nom1[20] ;
  4. char nom2[20] ;
  5. char nom3[20] ;
  6. char nom4[20] ;
  7. char nom5[20] ;
  8. char chaine[800] ;
  9. if(chaine==NULL)
  10. {
  11.  fprintf(stderr, "program exit\n" );
  12.  exit(EXIT_FAILURE) ;
  13. }
  14. char* chaine2 = (char*) malloc (sizeof(signed int)) ; //lecture entier par entier
  15. FILE* lire = NULL ;
  16. FILE* ecrire = NULL ;
  17. FILE* subsinoboot1 = NULL ;
  18. FILE* subsinoboot2 = NULL ;
  19. FILE* subsinoboot3 = NULL ;
  20. FILE* subsinoboot4 = NULL ;
  21. FILE* subsinoboot5 = NULL ;
  22. FILE* sino = NULL ;
  23. FILE* subsino1 = NULL ;
  24. FILE* subsino2 = NULL ;
  25. FILE* subsino3 = NULL ;
  26. FILE* subsino4 = NULL ;
  27. FILE* subsino5 = NULL ;
  28. int nb_ss_originaux , nb_ss_bootstrap , nb_sino ;
  29. long unsigned int sz_subsino , l ;
  30. int i , j , k , nb_al ;
  31. int nbsinocomplet ;
  32. float var ;
  33. signed long int val ;
  34. int test_fread ;
  35. int *tab_subsino1;
  36. int *tab_subsino2;
  37. int *tab_subsino3;
  38. int *tab_subsino4;
  39. int *tab_subsino5;
  40. int *tab_subsinotempo;
  41. int *tab_subsinoboot1;
  42. int *tab_subsinoboot2;
  43. int *tab_subsinoboot3;
  44. int *tab_subsinoboot4;
  45. int *tab_subsinoboot5;
  46. int *tab_sinoboot;
  47. // int nb_ssboot_par_somme ;
  48. test_fread = 0;
  49. nb_ss_originaux = 5;
  50. // nb_ssboot_par_somme = 5;
  51. printf("Le nombre de sous-sinogrammes originaux est fixé à 5.\n" ) ;
  52. printf("Combien de sinogrammes bootstraps voulez-vous obtenir?\n" ) ;
  53. scanf("%d",&nb_sino) ; /* == B' ;*/
  54. nb_ss_bootstrap = nb_ss_originaux * nb_sino;
  55. printf("%d sous-sinogrammes bootstrap seront utilises \n",nb_ss_bootstrap);
  56. lire=fopen("subsino1.s","rb" ) ;
  57. if (lire == NULL)
  58.     {
  59. printf("subsino1.s : ouverture impossible\n" );
  60.         exit(0);
  61.     }
  62. test_fread = fseek(lire,0,SEEK_END) ;
  63. if (test_fread != 0)
  64.     {
  65. printf("fread sur lire impossible\n" );
  66.         exit(0);
  67.     }
  68. sz_subsino=ftell(lire) ;
  69.  printf("sz_subsino = %lu \n",sz_subsino);
  70. rewind(lire) ;
  71. fclose(lire) ;
  72.  printf("fclose lire ok\n" );
  73.  i=0 ;
  74.  nbsinocomplet=0 ;
  75. /*initialisation à NULL*/
  76. init_tabptr(tab_subsino1,sz_subsino+1);
  77. init_tabptr(tab_subsino2,sz_subsino+1);
  78. init_tabptr(tab_subsino3,sz_subsino+1);
  79. init_tabptr(tab_subsino4,sz_subsino+1);
  80. init_tabptr(tab_subsino5,sz_subsino+1);
  81. /*initialisation à NULL*/
  82. init_tabptr(tab_subsinoboot1,sz_subsino+1);
  83. init_tabptr(tab_subsinoboot2,sz_subsino+1);
  84. init_tabptr(tab_subsinoboot3,sz_subsino+1);
  85. init_tabptr(tab_subsinoboot4,sz_subsino+1);
  86. init_tabptr(tab_subsinoboot5,sz_subsino+1);
  87.  printf("initialisations ok\n" );
  88. /***********************************************************************************/
  89. /* Allocation mémoire des sous-sinogrammes originaux : */
  90. subsino1=fopen("subsino1.s","rb" ) ;
  91. fseek(subsino1, 0L, SEEK_SET); /*replace le curseur au début du fichier*/
  92. tab_subsino1 = malloc(sz_subsino); /*allocation de l'espace mémoire (dans la RAM) pour le pointeur vers le subsino1*/
  93. test_fread = fread (tab_subsino1, 1, sz_subsino, subsino1); /*lecture de sz_subsino éléments de taille unitaire = 1 dans le fichier subsino1.s et rangement dans le fichier tab_subsino*/
  94. fclose(subsino1);
  95. if (tab_subsino1 == NULL || test_fread == 0) /*Si l'allocation mémoire a échoué*/
  96.     {
  97. printf("Echec de l'allocation mémoire pour tab_subsino1" );
  98.         exit(0); /*On arrête immédiatement le programme*/
  99.     }
  100. subsino2=fopen("subsino2.s","rb" ) ;
  101. fseek(subsino2, 0L, SEEK_SET);
  102. tab_subsino2 = malloc(sz_subsino);
  103. test_fread = fread (tab_subsino2, 1, sz_subsino, subsino2);
  104. fclose(subsino2);
  105. if (tab_subsino2 == NULL || test_fread == 0)
  106.     {
  107. printf("Echec de l'allocation mémoire pour tab_subsino1" );
  108.         exit(0);
  109.     }
  110. subsino3=fopen("subsino3.s","rb" ) ;
  111. fseek(subsino3, 0L, SEEK_SET);
  112. tab_subsino3 = malloc(sz_subsino);
  113. test_fread = fread (tab_subsino3, 1, sz_subsino, subsino3);
  114. fclose(subsino3);
  115. if (tab_subsino3 == NULL || test_fread == 0)
  116.     {
  117. printf("Echec de l'allocation mémoire pour tab_subsino1" );
  118.         exit(0);
  119.     }
  120. subsino4=fopen("subsino4.s","rb" ) ;
  121. fseek(subsino4, 0L, SEEK_SET);
  122. tab_subsino4 = malloc(sz_subsino);
  123. test_fread = fread (tab_subsino4, 1, sz_subsino, subsino4);
  124. fclose(subsino4);
  125. if (tab_subsino4 == NULL || test_fread == 0)
  126.     {
  127. printf("Echec de l'allocation mémoire pour tab_subsino1" );
  128.         exit(0);
  129.     }
  130. subsino5=fopen("subsino5.s","rb" ) ;
  131. fseek(subsino5, 0L, SEEK_SET);
  132. tab_subsino5 = malloc(sz_subsino);
  133. test_fread = fread (tab_subsino5, 1, sz_subsino, subsino5);
  134. fclose(subsino5);
  135. if (tab_subsino5 == NULL || test_fread == 0)
  136.     {
  137. printf("Echec de l'allocation mémoire pour tab_subsino1" );
  138.         exit(0);
  139.     }
  140. /***********************************************************************************/
  141. // #pragma omp for /*optimisation multi-thread*/
  142.  l=0 ;
  143.  k=0 ;
  144.  while(l<sz_subsino){
  145.   nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  146.   if(nb_al=1){tab_subsinotempo = tab_subsino1;}
  147.   if(nb_al=2){tab_subsinotempo = tab_subsino2;}
  148.   if(nb_al=3){tab_subsinotempo = tab_subsino3;}
  149.   if(nb_al=4){tab_subsinotempo = tab_subsino4;}
  150.   if(nb_al=5){tab_subsinotempo = tab_subsino5;}
  151.   for(k ; k<k+800 ; k++){
  152.   tab_subsinotempo[k] = tab_subsinoboot1[k];
  153.   } // for
  154.   l = l + 800;
  155.  } // while
  156.  l=0 ;
  157.  k=0 ;
  158.  while(l<sz_subsino){
  159.   nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  160.   if(nb_al=1){tab_subsinotempo = tab_subsino1;}
  161.   if(nb_al=2){tab_subsinotempo = tab_subsino2;}
  162.   if(nb_al=3){tab_subsinotempo = tab_subsino3;}
  163.   if(nb_al=4){tab_subsinotempo = tab_subsino4;}
  164.   if(nb_al=5){tab_subsinotempo = tab_subsino5;}
  165.   for(k ; k<k+800 ; k++){
  166.   tab_subsinotempo[k] = tab_subsinoboot2[k];
  167.   } // for
  168.   l = l + 800;
  169.  } // while
  170.  l=0 ;
  171.  k=0 ;
  172.  while(l<sz_subsino){
  173.   nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  174.   if(nb_al=1){tab_subsinotempo = tab_subsino1;}
  175.   if(nb_al=2){tab_subsinotempo = tab_subsino2;}
  176.   if(nb_al=3){tab_subsinotempo = tab_subsino3;}
  177.   if(nb_al=4){tab_subsinotempo = tab_subsino4;}
  178.   if(nb_al=5){tab_subsinotempo = tab_subsino5;}
  179.   for(k ; k<k+800 ; k++){
  180.   tab_subsinotempo[k] = tab_subsinoboot3[k];
  181.   } // for
  182.   l = l + 800;
  183.  } // while
  184.  l=0 ;
  185.  k=0 ;
  186.  while(l<sz_subsino){
  187.   nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  188.   if(nb_al=1){tab_subsinotempo = tab_subsino1;}
  189.   if(nb_al=2){tab_subsinotempo = tab_subsino2;}
  190.   if(nb_al=3){tab_subsinotempo = tab_subsino3;}
  191.   if(nb_al=4){tab_subsinotempo = tab_subsino4;}
  192.   if(nb_al=5){tab_subsinotempo = tab_subsino5;}
  193.   for(k ; k<k+800 ; k++){
  194.   tab_subsinotempo[k] = tab_subsinoboot4[k];
  195.   } // for
  196.   l = l + 800;
  197.  } // while
  198.  l=0 ;
  199.  k=0 ;
  200.  while(l<sz_subsino){
  201.   nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  202.   if(nb_al=1){tab_subsinotempo = tab_subsino1;}
  203.   if(nb_al=2){tab_subsinotempo = tab_subsino2;}
  204.   if(nb_al=3){tab_subsinotempo = tab_subsino3;}
  205.   if(nb_al=4){tab_subsinotempo = tab_subsino4;}
  206.   if(nb_al=5){tab_subsinotempo = tab_subsino5;}
  207.   for(k ; k<k+800 ; k++){
  208.   tab_subsinotempo[k] = tab_subsinoboot5[k];
  209.   } // for
  210.   l = l + 800;
  211.  } // while
  212. if (sino = NULL)
  213.      {
  214.         printf("Impossible d'ouvrir le fichier" );
  215.      }
  216.  printf("Création du sinogramme complet ok : flag 1.1\n" );
  217.  /*ouverture du sinogramme complet de sortie*/
  218.  sprintf(nom,"sino_complet%d.s",nbsinocomplet+1); /*création du sinogramme complet (vide)*/
  219.  printf("\ncréation du fichier de sortie (%s)\n",nom);
  220.  sino = fopen(nom,"w" );
  221. tab_sinoboot = malloc(sz_subsino); /*allocation mémoire (RAM) pour le pointeur vers le sinogramme bootstrap complet*/
  222.   printf("malloc sino ok : flag 1.4\n" );
  223. if (tab_sinoboot == NULL)
  224.     {
  225. printf("Echec de l'allocation mémoire pour tab_sinoboot" );
  226.         exit(0);
  227.     }
  228.  k=0 ;
  229. #pragma omp /*optimisation multi-thread*/
  230. for (k = 0 ; k < sz_subsino/sizeof(int) ; k++) {
  231.     tab_sinoboot[k] = tab_subsinoboot1[k] + tab_subsinoboot2[k] + tab_subsinoboot3[k] + tab_subsinoboot4[k] + tab_subsinoboot5[k]; /*somme pixel par pixel (dans la RAM) via les pointeurs sur les tableaux 2D des sinogrammes*/
  232. }
  233.  k=0 ;
  234. fwrite(tab_sinoboot, 1, sz_subsino, sino); /*ecriture de sz_subsino éléments de taille 1 du tableau tab_sino vers le fichier binaire du sinogramme bootstrap complet sino.*/
  235. fclose(sino);
  236. free(tab_subsinoboot1); /*libération de la mémoire*/
  237. free(tab_subsinoboot2);
  238. free(tab_subsinoboot3);
  239. free(tab_subsinoboot4);
  240. free(tab_subsinoboot5);
  241. free(tab_sinoboot);
  242. free(tab_subsino1);
  243. free(tab_subsino2);
  244. free(tab_subsino3);
  245. free(tab_subsino4);
  246. free(tab_subsino5);
  247.  nbsinocomplet++ ;
  248. } /*main*/


Message édité par Mourfizbak le 29-02-2012 à 11:16:56
n°2127975
gilou
Modérateur
Modzilla
Posté le 23-02-2012 à 13:15:17  profilanswer
 

Citation :

while(j<max) // somme des pixels de k=0 à k=max
 {
  fseek(subsino1,k,SEEK_SET) ; fseek(subsino2,k,SEEK_SET) ; fseek(subsino3,k,SEEK_SET) ; fseek(subsino4,k,SEEK_SET) ; fseek(subsino5,k,SEEK_SET); // décalage du curseur de k caractère à partir du début du fichier
  val = ( fgetc(subsino1) + fgetc(subsino2) + fgetc(subsino3) + fgetc(subsino4) + fgetc(subsino5) ) ;
  fputc(val,sino) ; // somme des pixels
  j++ ;
 } // while

Si tu fais ça pour chaque pixel et que tu en as 1 million, ça fait 11 million d'opération d'I/O environ (bon, un peu moins si tes fichiers sont bufferisés, mais quand même.
Rien d'étonnant à ce que ça rame! Surtout que tes fseek successifs impliquent à chaque fois un déplacement de la tête de lecture, si tu utilises  un HDD et non pas un SSD.
Tu doit faire tout en mémoire, et si jamais y'a pas assez de mémoire, tu lis par portion de fichier a chaque fois: Tu en traite X% en mémoire à la fois.
Tous les programmes de traitement d'image fonctionnent ainsi.

 

Et le pragma de parallélisation ne sert a rien ici, puisque les opérations d'I/O de lecture écriture positionnement disque ne sont pas parallélisables.

 

sinogramme? c'est des caractères chinois?

 

Tu vas faire un truc de ce genre ci:

 

subsino1 = fopen( nom1 , "r" ) ;
fseek(subsino1, 0L, SEEK_END);
sz_subsino1 = ftell(subsino1);
fseek(subsino1, 0L, SEEK_SET);
tab_subsino1 = malloc(sz_subsino1);
fread (tab_subsino1, 1, sz_subsino1, subsino1);
fclose(subsino1);
// idem pour les 4 autres comme ta taille est commune, ça peut se factoriser
sino=fopen(nom,"wb" );
tab_sino = malloc(sz_subsino1); // taille commune connue à l'avance
//
#pragma omp
// la c'est 100% vectorisable
for (i = 0; i < sz_subsino1; ++i) {
    tab_sino[i] = tab_subsino1[i] + tab_subsino2[i] + tab_subsino3[i] + tab_subsino4[i] + tab_subsino5[i];
}
fwrite(tab_sino, 1, sz_subsino1, sino);
fclose(sino);
free(tab_subsino1);
...
free(tab_subsino5);
free(tab_sino);

 

et ça devrait améliorer les choses.

 

A+,

Message cité 1 fois
Message édité par gilou le 23-02-2012 à 13:46:05

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2127976
in_your_ph​ion
Posté le 23-02-2012 à 13:20:42  profilanswer
 

Code :
  1. while(j<max) // somme des pixels de k=0 à k=max
  2. {
  3.   fseek(subsino1,k,SEEK_SET) ;
  4.   fseek(subsino2,k,SEEK_SET) ;
  5.   fseek(subsino3,k,SEEK_SET) ;
  6.   fseek(subsino4,k,SEEK_SET) ;
  7.   fseek(subsino5,k,SEEK_SET); // décalage du curseur de k caractère à partir du début du fichier
  8.   val = ( fgetc(subsino1) + fgetc(subsino2) + fgetc(subsino3) + fgetc(subsino4) + fgetc(subsino5) ) ;
  9.   fputc(val,sino) ; // somme des pixels
  10.   j++ ;
  11. } // while
 

c'est clairement là dedans que tu perds du temps je pense. Tu ne devrais pas faire le travail de ton algorithme en piochant les valeurs dans des fichiers... C'est sûr que ce n'est du tout optimal. Par ailleurs tu fais des écritures avec fput() c'est pareil => long et non adapté.

 

A mon sens, je ferais :
- ouvrir les fichiers
- créer des tableaux de valeurs qui stockent les données des fichiers (cad tab1 pour subsino1, ...). Tout sera donc stocké en RAM.
- fermer les fichiers.
- faire le traitement en accédants aux données des tableaux et non pas celles des fichiers (long ...) et stocker le résultat dans un nouveau tableau
- ouvrir des fichiers pour le résultat
- écrire le tableau résultat dedans
- fermer les fichiers de résultat

 

Tu as essayé ça ? Je pense que ça ira bien plus vite ... Ton programme ne doit intégrer des accès I/O qu'au début et à la fin, pas dans ton algorithme !


Message édité par in_your_phion le 23-02-2012 à 14:40:42
n°2127980
Mourfizbak
Posté le 23-02-2012 à 13:55:34  profilanswer
 

gilou a écrit :

[quote]
sinogramme? c'est des caractères chinois?


 
Point du tout ^^. En gros il s'agit des images brutes (avant reconstruction) enregistrées lors d'une tomographie à émission de positrons (PET) utilisé en médecine nucléaire.
 
Merci pour votre aide, vos idées sont très proches. Je vais m'employer à modifier mon programme dans ce sens, et je reviendrai poster les conclusions quand tout marchera. Ca peut être utile à quelqu'un d'autre, sait-on jamais !
 
Merci encore !:)


Message édité par Mourfizbak le 23-02-2012 à 13:55:56
n°2127984
gilou
Modérateur
Modzilla
Posté le 23-02-2012 à 14:17:23  profilanswer
 

Vérifies les retours des mallocs pour vérifier que les allocations mémoires se passent bien.
Sinon il faudra ajuster le % de fichier lu à chaque fois et faire ça en plusieurs fois avec une boucle.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2128485
Mourfizbak
Posté le 27-02-2012 à 10:03:34  profilanswer
 

Bonjour !
Dernière petite galère :
J'ai un bug au niveau des
 

Code :
  1. fseek(subsino3, 0L, SEEK_SET);
  2. tab_subsino3 = malloc(sz_subsino);
  3. fread (tab_subsino3, 1, sz_subsino, subsino3);
  4. fclose(subsino3);
  5. if (tab_subsino3 == NULL)
  6.     {
  7. printf("Echec de l'allocation mémoire pour tab_subsino3" );
  8.         exit(0);


 
tab_subsino3 (en l'occurence, mais bien entendu c'est la même pour les 4 autres) est rempli de données égales à 0 (y'a le bon nombre de données par contre). Du coup j'aboutis à une erreur de segmentation à :
 

Code :
  1. for (k = 0; k < sz_subsino; k++) {
  2.     tab_sino[k] = tab_subsino1[k] + tab_subsino2[k] + tab_subsino3[k] + tab_subsino4[k] + tab_subsino5[k]; /*somme pixel par pixel (dans la RAM) via les pointeurs sur les tableaux 2D des sinogrammes*/
  3. }


 
Je suis sûr de mes fichiers binaires "subsino"...J'ai planché tout le week-end sur le sujet, je sèche, si quelqu'un a une idée ?!
 
Merci d'avance :)


Message édité par Mourfizbak le 27-02-2012 à 10:04:26
n°2128495
Mourfizbak
Posté le 27-02-2012 à 10:43:06  profilanswer
 

Petite simplification du problème pour vous éviter la lecture de tout le topic depuis le début :
 
Je dispose de 5 fichiers binaires volumineux (>1 Go) appelés subsino1 ... subsino5.
J'ai donc créé 5 tableaux :
 

Code :
  1. int* tab_subsino1 = NULL;


 
puis copié le contenu des subsino dans ces tableaux pour faciliter le traitement par la suite :
 

Code :
  1. subsino1 = fopen( nom1 , "rb" ) ;
  2. fseek(subsino1, 0L, SEEK_SET);
  3. tab_subsino1 = malloc(sz_subsino);
  4. fread (tab_subsino1, 1, sz_subsino, subsino1);
  5. fclose(subsino1);
  6. if (tab_subsino1 == NULL)
  7.     {


 
J'ai besoin ensuite de sommer chaque tab_subsino[i] dans un tab_sino, mais les tab_subsino[i] sont tous égaux à 0, et lors de la somme j'obtiens une erreur de segmentation...
Je ne parviens par à comprendre le pourquoi du comment.
 
Merci d'avance pour votre aide ! :-)

n°2128503
gilou
Modérateur
Modzilla
Posté le 27-02-2012 à 11:52:25  profilanswer
 

1) Tes fichier de données sont bien des fichiers binaires, écrits comme une suite d'ints, sans le moindre retour de ligne ou autre?
2) Tu as teste les codes de retour de chaque appel?  
en particulier le malloc et le fread
si tu as une erreur de segmentation ici:
tab_sino[i] = tab_subsino1[i] + tab_subsino2[i] + tab_subsino3[i] + tab_subsino4[i] + tab_subsino5[i]
ça tend à me faire penser que pour une valeur de i et un des 5 tableaux tab_subsinoX, tab_subsinoX[i] est en dehors des bornes de son allocation, et donc que tes fichiers de donnée auraient pas tous la même taille à l'octet près.
Car même si tes tableaux étaient remplis de données nulles, en aucun cas cela ne provoquerait de segmentation.
 
D'autrepart:
subsino1 = fopen( nom1 , "rb" ) ;
fseek(subsino1, 0L, SEEK_SET);
tab_subsino1 = malloc(sz_subsino1);
 
J'avais mis  
subsino1 = fopen( nom1 , "r" ) ;
fseek(subsino1, 0L, SEEK_END);
sz_subsino1 = ftell(subsino1);

fseek(subsino1, 0L, SEEK_SET);
tab_subsino1 = malloc(sz_subsino1);
 
Si tu calcules pas la taille à allouer, ça risque pas de marcher (et si la taille des 5 fichiers est pas la même, c'est qu'il y a qque chose d'incorrect).
 
Au fait, c'est bien du binaire qu'il y a dans tes fichiers, ie ils ont bien été écrits avec un fwrite (parce que si c'était autrement, ça changerait la manière de les lire)
 
A+,


Message édité par gilou le 27-02-2012 à 12:16:33

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2128510
Mourfizbak
Posté le 27-02-2012 à 12:22:52  profilanswer
 

1) Pas de soucis pour les fichiers binaires, ils sont bien écrits comme une suite propre d'ints (puisque traités par ImageJ comme tel sans aucun soucis).
2) Oui, j'ai suivi vos conseils de la semaine dernière et testé l'intégralité des retours des malloc et fread.
 
Voici le code complet (amputé du générateur aléatoire pour plus de lisibilité) :
 

Code :
  1. /*
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5. static int left = 1;
  6. static unsigned long *next;
  7. static unsigned long state[N]; /* the array for the state vector  */
  8. static int initf = 0;
  9. /* initializes state[N] with a seed */
  10. int main(){
  11. sched_getaffinity();
  12. char nom[20] ;
  13. char nom1[20] ;
  14. char nom2[20] ;
  15. char nom3[20] ;
  16. char nom4[20] ;
  17. char nom5[20] ;
  18.  
  19. char chaine[800] ;
  20. if(chaine==NULL)
  21. {
  22.  fprintf(stderr, "program exit\n" );
  23.  exit(EXIT_FAILURE) ;
  24. }
  25.  
  26. char* chaine2 = (char*) malloc (sizeof(signed int)) ; //lecture entier par entier
  27.  
  28. FILE* lire = NULL ;
  29. FILE* ecrire = NULL ;
  30. FILE* subsino1 = NULL ;
  31. FILE* subsino2 = NULL ;
  32. FILE* subsino3 = NULL ;
  33. FILE* subsino4 = NULL ;
  34. FILE* subsino5 = NULL ;
  35. FILE* sino = NULL ;
  36.  
  37.  
  38. int nb_ss_originaux , nb_ss_bootstrap , nb_sino ;
  39. long int sz_subsino , l ;
  40. int i , j , k , nb_al ;
  41. int nbsinocomplet ;
  42. float var ;
  43. signed long int val ;
  44. int test_fread ;
  45.  
  46. int* tab_subsino1 = NULL;
  47. int* tab_subsino2 = NULL;
  48. int* tab_subsino3 = NULL;
  49. int* tab_subsino4 = NULL;
  50. int* tab_subsino5 = NULL;
  51. int* tab_sino = NULL;
  52. nb_ss_originaux = 5;
  53. printf("Le nombre de sous-sinogrammes originaux est fixé à 5.\n" ) ;
  54. printf("Combien de sinogrammes bootstraps voulez-vous obtenir?\n" ) ;
  55. scanf("%d",&nb_sino) ; // == B' ;*/
  56. nb_ss_bootstrap = nb_ss_originaux * nb_sino;
  57. printf("%d sous-sinogrammes bootstrap seront utilises \n",nb_ss_bootstrap);
  58. /*printf("\ncalcul de la taille du fichier\n" ) ;*/
  59. lire=fopen("subsino1.s","rb" ) ;
  60. fseek(lire,0,SEEK_END) ;
  61. /*printf("le fichier fait %ld octets\n\n",ftell(lire)) ;*/
  62. sz_subsino=ftell(lire) ;
  63. rewind(lire) ;
  64. fclose(lire) ;
  65.  i=0 ;
  66.  j=0 ;
  67.  test_fread = 0;
  68.  nbsinocomplet=0 ;
  69. #pragma omp parallel for /*optimisation multi-thread*/
  70. for (i=0;i<nb_ss_bootstrap;i+=5){
  71. #pragma omp parallel for /*optimisation multi-thread*/
  72. for (j=0;j<5;j++){
  73.  sprintf(nom,"subsino%d.s",nb_ss_originaux+j+1) ; /*nom = sous-sinogramme original n°j*/
  74.  ecrire=fopen(nom,"wb" ) ;/*écriture du sous-sinogramme n°nb_ss_originaux+i+1*/
  75.  l=0 ;
  76.  while(l<sz_subsino){
  77.   nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  78.   sprintf(nom2,"subsino%d.s",nb_al) ; /*choix aléatoire d'un des N sous-sinogrammes*/
  79.   lire=fopen(nom2,"rb" ) ;
  80.   fseek(lire,l,SEEK_SET) ; /*positionne le curseur au début et le décale de l caractères (pour se placer sur la bonne ligne du sous-sinogramme pris aléatoirement)*/
  81.   fread(chaine,sizeof(char),800,lire) ; /*sauvegarde de la ligne "chaine" dans le fichier lire (nouveau sinogramme)*/
  82.   fwrite(chaine,sizeof(chaine),1,ecrire) ; /*écriture de la ligne "chaine" dans le sous-sinogramme bootstrap en cours*/
  83.   l+=800 ; /*passage à la ligne suivante*/
  84.   fclose(lire) ;
  85.   nb_al=0; // Utilité ???
  86.  } /*while*/
  87.  /*printf("le subsinogramme %d a été créé avec succès\n",nb_ss_originaux+j+1) ;*/
  88.  fclose(ecrire) ;
  89. } /*for sur j (5 subsinogrammes ont été créés avec succès)*/
  90. printf("\ncréation du sinogramme bootstrap %d\n",nbsinocomplet+1) ;
  91.  sprintf(nom1,"subsino1.s" ); /*nom1 = sous-sinogramme N+1*/
  92.  sprintf(nom2,"subsino2.s" );
  93.  sprintf(nom3,"subsino3.s" );
  94.  sprintf(nom4,"subsino4.s" );
  95.  sprintf(nom5,"subsino5.s" );
  96.  /*printf("les subsinos utilisés seront: %s, %s, %s, %s, %s\n",nom1,nom2,nom3,nom4,nom5) ;*/
  97.  subsino1 = fopen( nom1 , "rb" ) ;
  98.  subsino2 = fopen( nom2 , "rb" ) ;
  99.  subsino3 = fopen( nom3 , "rb" ) ;
  100.  subsino4 = fopen( nom4 , "rb" ) ;
  101.  subsino5 = fopen( nom5 , "rb" ) ;
  102. if (sino = NULL)
  103.      {
  104.         printf("Impossible d'ouvrir le fichier" );
  105.      }
  106.  printf("Création du sinogramme complet ok : flag 1.1\n" );
  107. fseek(subsino1, 0L, SEEK_SET); /*replace le curseur au début du fichier*/
  108. tab_subsino1 = malloc(sz_subsino); /*allocation de l'espace mémoire (dans la RAM) pour le pointeur vers le subsino1*/
  109. test_fread = fread (tab_subsino1, 1, sz_subsino, subsino1); /*lecture de sz_subsino éléments de taille unitaire = 1 dans le fichier subsino 1 et rangement dans le fichier tab_subsino*/
  110. fclose(subsino1);
  111. if (tab_subsino1 == NULL || test_fread == 0) /*Si l'allocation mémoire a échoué*/
  112.     {
  113. printf("Echec de l'allocation mémoire pour tab_subsino1" );
  114.         exit(0); /*On arrête immédiatement le programme*/
  115.     }
  116. fseek(subsino2, 0L, SEEK_SET);
  117. tab_subsino2 = malloc(sz_subsino);
  118. test_fread = fread (tab_subsino2, 1, sz_subsino, subsino2);
  119. fclose(subsino2);
  120.  printf("resultat fread sur tabsubsino2 : %d \n",test_fread);
  121. if (tab_subsino2 == NULL || test_fread == 0)
  122.     {
  123. printf("Echec de l'allocation mémoire pour tab_subsino2" );
  124.         exit(0);
  125.     }
  126. fseek(subsino3, 0L, SEEK_SET);
  127. tab_subsino3 = malloc(sz_subsino);
  128. test_fread = fread (tab_subsino3, 1, sz_subsino, subsino3);
  129. fclose(subsino3);
  130. if (tab_subsino3 == NULL || test_fread == 0)
  131.     {
  132. printf("Echec de l'allocation mémoire pour tab_subsino3" );
  133.         exit(0);
  134.     }
  135. fseek(subsino4, 0L, SEEK_SET);
  136. tab_subsino4 = malloc(sz_subsino);
  137. test_fread = fread (tab_subsino4, 1, sz_subsino, subsino4);
  138. fclose(subsino4);
  139. if (tab_subsino4 == NULL || test_fread == 0)
  140.     {
  141. printf("Echec de l'allocation mémoire pour tab_subsino4" );
  142.         exit(0);
  143.     }
  144. fseek(subsino5, 0L, SEEK_SET);
  145. tab_subsino5 = malloc(sz_subsino);
  146. test_fread = fread (tab_subsino5, 1, sz_subsino, subsino5);
  147. fclose(subsino5);
  148. if (tab_subsino5 == NULL || test_fread == 0)
  149.     {
  150. printf("Echec de l'allocation mémoire pour tab_subsino5" );
  151.         exit(0);
  152.     }
  153.   printf("malloc subsino ok flag 1.2\n" );
  154.  /*ouverture du sinogramme complet de sortie*/
  155.  sprintf(nom,"sino_complet%d.s",nbsinocomplet+1); /*création du sinogramme complet (vide)*/
  156.   printf("création du sino complet ok : flag 1.3\n" );
  157.  printf("\ncréation du fichier de sortie (%s)\n",nom);
  158.  sino = fopen(nom,"w" );
  159. tab_sino = malloc(sz_subsino); /*allocation mémoire (RAM) pour le pointeur vers le sinogramme bootstrap complet*/
  160.   printf("malloc sino ok : flag 1.4\n" );
  161. if (tab_sino == NULL)
  162.     {
  163. printf("Echec de l'allocation mémoire pour tab_sino" );
  164.         exit(0);
  165.     }
  166. #pragma omp /*ptimisation multi-thread*/
  167.  k=0 ;
  168.   printf("tab_sino[sz_subsino-1]=%d : flag 1.5\n",tab_sino[sz_subsino-1]);
  169.   printf("tab_subsino1[sz_subsino-1]=%d : flag 1.6\n",tab_subsino1[sz_subsino-2]);
  170.   printf("tab_subsino2[sz_subsino-1]=%d : flag 1.7\n",tab_subsino2[sz_subsino-1]);
  171.   printf("tab_subsino3[sz_subsino-1]=%d : flag 1.8\n",tab_subsino3[sz_subsino-1]);
  172.   printf("tab_subsino4[sz_subsino-1]=%d : flag 1.9\n",tab_subsino4[sz_subsino-1]);
  173.   printf("tab_subsino4[sz_subsino-1]=%d : flag 1.9\n",tab_subsino5[sz_subsino-1]);
  174. for (k = 0; k < sz_subsino; k++) {
  175.     tab_sino[k] = tab_subsino1[k] + tab_subsino2[k] + tab_subsino3[k] + tab_subsino4[k] + tab_subsino5[k]; /*somme pixel par pixel (dans la RAM) via les pointeurs sur les tableaux 2D des sinogrammes*/
  176. }
  177.  printf("Boucle sur tab_sino ok : flag 2" );
  178. fwrite(tab_sino, 1, sz_subsino, sino); /*criture de sz_subsino éléments de taille 1 du tableau tab_sino vers le fichier binaire du sinogramme bootstrap complet sino.*/
  179. fclose(sino);
  180.  printf("Ecriture dans sino ok : flag 3" );
  181. free(tab_subsino1); /*ibération de la mémoire*/
  182. free(tab_subsino2);
  183. free(tab_subsino3);
  184. free(tab_subsino4);
  185. free(tab_subsino5);
  186. free(tab_sino);
  187.  printf("Libération mémoire ok : flag 4" );
  188.  nbsinocomplet++ ;
  189. remove("subsino6.s" );
  190. remove("subsino7.s" );
  191. remove("subsino8.s" );
  192. remove("subsino9.s" );
  193. remove("subsino10.s" );
  194.  printf("les subsinogrammes bootstrap ont été supprimé avec succès\n" ) ;
  195. } /*for sur i => tous les ss_bootstrap sont créés*/
  196. printf("\nla création de sub-sinogrammes bootstraps est terminée\n" ) ;
  197. } /*main*/


 
Et voici ce que me rend le terminal :
 
création du sinogramme bootstrap 1
Création du sinogramme complet ok : flag 1.1
resultat fread sur tabsubsino2 : 1168473600  
malloc subsino ok flag 1.2
création du sino complet ok : flag 1.3
 
création du fichier de sortie (sino_complet1.s)
malloc sino ok : flag 1.4
tab_sino[sz_subsino-1]=0 : flag 1.5
Erreur de segmentation
 
Je ne comprend pas comment tab_subsino5[sz_subsino-1] peut renvoyer une erreur d'allocation...o_O"


Message édité par Mourfizbak le 27-02-2012 à 12:25:07
n°2128516
shaoyin
Posté le 27-02-2012 à 13:03:27  profilanswer
 

Quel est le type de ta variable sz_subsino ? Tu as peut-être un dépassement de capacité à la ligne 76, qui fait que tu n'alloues pas la quantité qu'il faut ? Cela n'explique pas l'erreur de segmentation, mais c'est une source d'erreur.
Vu qu'elle contient une taille de fichier, elle devrait au moins être "unsigned int".
 
EDIT : Heu.... ligne 212, ce ne serait pas "sz_subsino-1" plutôt que "sz_subsino-2" ?

Message cité 1 fois
Message édité par shaoyin le 27-02-2012 à 13:11:38
n°2128524
gilou
Modérateur
Modzilla
Posté le 27-02-2012 à 13:39:31  profilanswer
 

Citation :

fseek(lire,l,SEEK_SET) ; /*positionne le curseur au début et le décale de l caractères (pour se placer sur la bonne ligne du sous-sinogramme pris aléatoirement)*/


Cela peut marcher, mais ce n'est pas certain. Il vaudrait mieux s'assurer que vos découpages se font suivant un multiple de sizeof(int)
 
Bon sinon, j'ai pigé:
for (k = 0; k < sz_subsino; k++) {
 
C'est  
for (k = 0; k < sz_subsino/sizeof(int); k++) {
 
en effet, sz_subsino est la taille en octet, mais les pointeurs sont sur des entiers, et vont donc se déplacer de plus d'un octet à la fois. C'est pour ça qu'on dépasse la capacité du tableau et qu'on a une erreur de segmentation.
 
A+,

Message cité 1 fois
Message édité par gilou le 27-02-2012 à 13:39:58

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2128527
Mourfizbak
Posté le 27-02-2012 à 13:59:10  profilanswer
 

shaoyin a écrit :

Quel est le type de ta variable sz_subsino ? Tu as peut-être un dépassement de capacité à la ligne 76, qui fait que tu n'alloues pas la quantité qu'il faut ? Cela n'explique pas l'erreur de segmentation, mais c'est une source d'erreur.
Vu qu'elle contient une taille de fichier, elle devrait au moins être "unsigned int".
 
EDIT : Heu.... ligne 212, ce ne serait pas "sz_subsino-1" plutôt que "sz_subsino-2" ?


 
Pas de soucis pour la ligne 212, c'est juste des printf pour voir où était le problème...
 

gilou a écrit :

Citation :

fseek(lire,l,SEEK_SET) ; /*positionne le curseur au début et le décale de l caractères (pour se placer sur la bonne ligne du sous-sinogramme pris aléatoirement)*/


Cela peut marcher, mais ce n'est pas certain. Il vaudrait mieux s'assurer que vos découpages se font suivant un multiple de sizeof(int)
 
Bon sinon, j'ai pigé:
for (k = 0; k < sz_subsino; k++) {
 
C'est  
for (k = 0; k < sz_subsino/sizeof(int); k++) {
 
en effet, sz_subsino est la taille en octet, mais les pointeurs sont sur des entiers, et vont donc se déplacer de plus d'un octet à la fois. C'est pour ça qu'on dépasse la capacité du tableau et qu'on a une erreur de segmentation.
 
A+,


 
C'était effectivement ça, merci beaucoup, jamais je n'aurai pensé à ça !
 
Grâce aux idées de ce forum, mon programme marche (seulement pour le cas simple pour le moment ^^) et j'ai gagné un facteur 10 sur le temps d'exécution  :D  
 
Un grand merci à vous  :bounce:  

n°2128528
gilou
Modérateur
Modzilla
Posté le 27-02-2012 à 14:23:27  profilanswer
 

Bon, pour voir si on peut encore améliorer cela, pourrais tu m'expliquer exactement comment tu procedes, ie les boucles
for (i=0;i<nb_ss_bootstrap;i+=5){
for (j=0;j<5;j++){
 
IE: tu as quoi au départ comme fichier, et tu génères quoi ensuite comme fichiers a partir de ce que tu as au départ (le comment de la génération aléatoire, pas de pb. Le 800 qui apparaît dedans, c'est parce que tes sous-sinogrammes font 800 ints?)
Bref, si tu m'expliques clairement les fichiers de départ (avec les noms), les générés intermédiaires (avec leurs noms) je comprendrais mieux la logique de l'ensemble (car j'ai pas vraiment pigé le pourquoi de ta boucle principale bornée par nb_ss_bootstrap)
 
A+,

Message cité 1 fois
Message édité par gilou le 27-02-2012 à 14:23:52

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2128530
Mourfizbak
Posté le 27-02-2012 à 14:46:56  profilanswer
 

gilou a écrit :

Bon, pour voir si on peut encore améliorer cela, pourrais tu m'expliquer exactement comment tu procedes, ie les boucles
for (i=0;i<nb_ss_bootstrap;i+=5){
for (j=0;j<5;j++){
 
IE: tu as quoi au départ comme fichier, et tu génères quoi ensuite comme fichiers a partir de ce que tu as au départ (le comment de la génération aléatoire, pas de pb. Le 800 qui apparaît dedans, c'est parce que tes sous-sinogrammes font 800 ints?)
Bref, si tu m'expliques clairement les fichiers de départ (avec les noms), les générés intermédiaires (avec leurs noms) je comprendrais mieux la logique de l'ensemble (car j'ai pas vraiment pigé le pourquoi de ta boucle principale bornée par nb_ss_bootstrap)
 
A+,


 
Au départ, je pars de N sous-sinogrammes originaux (N = nb_ss_originaux, pour l'instant égal à 5, à terme sûrement plutôt 25). Par un procédé de tirage aléatoire avec remise (méthode bootstrap), j'en retire B sous-sinogrammes boostrap (B = nb_ss_bootstrap). En sommant ces sous-sinogrammes (notés subsino1,...,subsino5) 5 par 5, j'en retire B'=B/N (soit nb_ss_bootstrap / nb_ss_originaux) sinogrammes bootstrap (noté nb_sino). C'est cette valeur qui est importante et qu'il faut rentrer dans le programme (et qui, pour l'instant, si elle est supérieure à 1 donne une erreur de segmentation dés le tout début du programme  :heink: )
 
Les 5 sous-sinogrammes boostrap n'ayant plus aucun intérêt une fois sommés, je les supprime pour libérer 5,5Go d'espace disque.
 
Pour l'instant, mon programme marche pour 1 seul sinogramme bootstrap, et je suis en train de le débuguer pour qu'il marche pour la création de B' sinogrammes bootstrap...
 
Voilà, vous savez tout !  :)
 
Mais comme la grande majorité du temps d'exécution est apparemment due à l'écriture des sous-sinogrammes bootstrap sur le disque, je ne pense pas qu'une meilleure optimisation soit possible...


Message édité par Mourfizbak le 27-02-2012 à 15:27:58
n°2128550
gilou
Modérateur
Modzilla
Posté le 27-02-2012 à 16:41:59  profilanswer
 

Je regarde ça ce soir à tête reposée et je posterai des commentaires.
Un premier:

Code :
  1. char chaine[800] ;
  2. if(chaine==NULL)
  3. {
  4. fprintf(stderr, "program exit\n" );
  5. exit(EXIT_FAILURE) ;
  6. }


comme chaine est alloué à la compilation, il lui est impossible d'être NULL, le test est inutile.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2128561
gilou
Modérateur
Modzilla
Posté le 27-02-2012 à 18:26:58  profilanswer
 

Citation :

Les 5 sous-sinogrammes boostrap n'ayant plus aucun intérêt une fois sommés, je les supprime pour libérer 5,5Go d'espace disque.

Sauf que le programme actuel fait la sommation sur les ss_originaux et non pas sur les ss_bootstrap si j'ai bien suivi (et les ss_bootstrap, inutile de les écrire sur disque, autant les garder en mémoire).
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2128593
gilou
Modérateur
Modzilla
Posté le 28-02-2012 à 02:05:26  profilanswer
 

Si pour un fichier en sortie, sommer 5 bootstraps générés successivement te convient, alors ceci n'est ni gourmand en I/O (on ne lit et n’écrit rien d'intermédiaire, tout est en mémoire)
Tu fais 1 + nb_ss_originaux lectures d'un fichier et nb_sino ecritures d'un fichier
Et en mémoire, les tables occupent 1+ 2*nb_ss_originaux fois la taille d'un fichier de donnée
Donc pour 25 fichiers originaux de 1 Go, ça devrait bouffer un peu plus de 50 Go de mémoire, ce qui est dans les cordes de ta machine.
C'est pas garanti sans bugs, mais sur de petits fichiers tests ou je passais dans toutes les boucles, ça passe OK.
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <string.h>
  5. // Vu le manque facilités pour manipuler les tableaux dynamiques en C
  6. typedef struct {
  7.     int nb_tab;
  8.     long size_tab;
  9.     int **ss_tab;  // int sstab[nb_tab][size_tab] table à nb_tab elements de tables de size_tab pixels
  10. } t_ss;
  11. // fonction auxiliaire qui retourne le taille d'un fichier en octet
  12. // retourne -1 en cas d'échec
  13. long file_size(char *fname) { // court-circuiter si la taille est connue à l'avance
  14.     FILE *fichier;
  15.     long taille = -1L;
  16.     fichier = fopen(fname, "rb" );
  17.     if (!fichier) {
  18.         printf("Echec de la lecture de %s\n", fname);
  19.     }
  20.     else {
  21.         taille = fseek(fichier, 0, SEEK_END);
  22.         if (taille == -1) {
  23.             printf("Echec de positionnement en fin de %s\n", fname);
  24.         }
  25.         else {
  26.             taille = ftell(fichier);
  27.             if (taille == -1) {
  28.                 printf("Echec de la lecture de la taille de %s\n", fname);
  29.             }
  30.         }
  31.         fclose(fichier);
  32.     }
  33.     return taille;
  34. }
  35. // libération de la mémoire allouée dans un pointeur sur une structure t_ss
  36. void ss_free(t_ss *tables) {
  37.     while(tables->nb_tab) {
  38.         free(tables->ss_tab[--tables->nb_tab]);
  39.     }
  40.     free(tables->ss_tab);
  41.     free(tables);
  42. }
  43. // creation d'un pointeur sur une structure t_ss avec num_tab tables de tab_size pixels
  44. // ou NULL si echec
  45. t_ss *ss_create(int num_tab, long size_tab) {
  46.     int i;
  47.     t_ss *tables;
  48.     tables = malloc(sizeof(t_ss));
  49.     if (tables) {
  50.         tables->nb_tab = 0;
  51.         tables->size_tab = size_tab;
  52.         tables->ss_tab = malloc(num_tab * sizeof(int*));
  53.         if (tables->ss_tab) {
  54.             for (i = 0; i <  num_tab; ++i) {
  55.                 tables->ss_tab[i] = malloc(size_tab * sizeof(int));
  56.                 if (tables->ss_tab[i]) {
  57.                     ++tables->nb_tab; // met a jour le nb de tables effectivement allouées
  58.                 }
  59.                 else {
  60.                     // marche parce que tables->nb_tab est le nombre de celles effectivement allouées
  61.                     ss_free(tables);
  62.                     tables = NULL;
  63.                     break;
  64.                 }
  65.             }
  66.         }
  67.         else {
  68.             free(tables);
  69.             tables = NULL;
  70.         }
  71.     }
  72.     return tables;
  73. }
  74. int main() {
  75.     t_ss *ss_originaux, *ss_bootstraps, *ss_final;
  76.     int nb_ss_originaux, nb_ss_bootstraps, nb_sino, nb_al;
  77.     long ss_size, nb_read, nb_pixels, l;
  78.     char nom[20];
  79.     FILE *lire, *ecrire;
  80.     int i, j, frame_size;
  81.     // sched_getaffinity();
  82.     nb_ss_originaux = 5;
  83.     nb_ss_bootstraps = nb_ss_originaux;
  84.     ss_size = file_size("subsino1.s" );
  85.     if (ss_size % sizeof(int)) {
  86.         printf("Alerte: taille de subsino1.s incorrecte. Lecture du fichier tronquée.\n" );
  87.     }
  88.     nb_pixels = ss_size / sizeof(int);
  89.     // creation de la table des ss_originaux
  90.     ss_originaux = ss_create(nb_ss_originaux, nb_pixels);
  91.     if (!ss_originaux) {
  92.         printf("Echec de creation pour la structure des sous-sinogrammes originaux\n" );
  93.         exit(EXIT_FAILURE);
  94.     }
  95.     // remplissage de la table des ss_originaux
  96.     for (i = 0; i < nb_ss_originaux; ++i) {
  97.         snprintf(nom, 20, "subsino%d.s", i+1);
  98.         lire = fopen(nom, "rb" );
  99.         if (lire) {
  100.             nb_read = fread(ss_originaux->ss_tab[i], sizeof(int), nb_pixels, lire);
  101.             fclose(lire);
  102.             if (nb_read != nb_pixels) {
  103.                 ss_free(ss_originaux);
  104.                 printf("Erreur lors de la lecture de %s\n", nom);
  105.                 exit(EXIT_FAILURE);
  106.             }
  107.         }
  108.         else {
  109.             ss_free(ss_originaux);
  110.             printf("Echec de la lecture de %s\n", nom);
  111.             exit(EXIT_FAILURE);
  112.         }
  113.     }
  114.     // creation de la table des ss_auxiliaire
  115.     ss_bootstraps = ss_create(nb_ss_bootstraps, nb_pixels);
  116.     if (!ss_bootstraps) {
  117.         ss_free(ss_originaux);
  118.         printf("Echec de creation pour la structure des sous-sinogrammes auxiliaires\n" );
  119.         exit(EXIT_FAILURE);
  120.     }
  121.     // creation du ss_final
  122.     ss_final = ss_create(1, nb_pixels);
  123.     if (!ss_final) {
  124.         ss_free(ss_originaux);
  125.         ss_free(ss_bootstraps);
  126.         printf("Echec de creation pour la structure du sous-sinogrammes bootstraps\n" );
  127.         exit(EXIT_FAILURE);
  128.     }
  129.     printf("Le nombre de sous-sinogrammes originaux est fixé à %d.\n", nb_ss_originaux) ;
  130.     printf("Combien de sinogrammes finaux voulez-vous obtenir?\n" ) ;
  131.     scanf("%d", &nb_sino) ; // == B' ;*/
  132.     frame_size = 800;
  133.     for (i = 0; i < nb_sino; ++i) {
  134.         // remplissage des pixels des ss bootstrap
  135.         for (j = 0; j < nb_ss_bootstraps; ++j) {
  136.             l = 0;
  137.             while ((nb_pixels - l) > frame_size) {
  138.                 nb_al = genrand_real2()*nb_ss_originaux; // valeurs de 0 à nb_ss_originaux - 1
  139.                 memcpy(ss_bootstraps->ss_tab[j]+l, ss_originaux->ss_tab[nb_al]+l, frame_size*sizeof(int));
  140.                 l+= frame_size;
  141.             }
  142.             nb_al = genrand_real2()*nb_ss_originaux;
  143.             memcpy(ss_bootstraps->ss_tab[j]+l, ss_originaux->ss_tab[nb_al]+l, (nb_pixels - l)*sizeof(int));
  144.         }
  145.         // remplissage des pixels de ss final
  146.         for (l = 0; l < nb_pixels; ++l) {
  147.             ss_final->ss_tab[0][l] = 0;
  148.             for (j = 0; j < nb_ss_bootstraps; ++j) {
  149.                 ss_final->ss_tab[0][l] += ss_bootstraps->ss_tab[j][l];
  150.             }
  151.         }
  152.         // ecriture de ss final
  153.         snprintf(nom, 20, "sino_complet%d.s", i+1);
  154.         ecrire = fopen(nom,"w" );
  155.         if (!ecrire) {
  156.             ss_free(ss_originaux);
  157.             ss_free(ss_bootstraps);
  158.             ss_free(ss_final);
  159.             printf("Echec de la creation de de %s\n", nom);
  160.             exit(EXIT_FAILURE);
  161.         }
  162.         l = fwrite(ss_final->ss_tab[0], 1, ss_size, ecrire);
  163.         fclose(ecrire);
  164.         if (l == -1) {
  165.             ss_free(ss_originaux);
  166.             ss_free(ss_bootstraps);
  167.             ss_free(ss_final);
  168.             printf("Echec de l'ecriture de de %s\n", nom);
  169.             exit(EXIT_FAILURE);
  170.         }
  171.     } // boucle jusqu'a ce qu'on en ait écrit nb_sino fichiers finaux
  172.     ss_free(ss_originaux);
  173.     ss_free(ss_bootstraps);
  174.     ss_free(ss_final);
  175.     exit(EXIT_SUCCESS);
  176. }


 
Par contre, si tu tiens a générer tous les bootstraps d'un coup (faudra réécrire un peu, mais c'est pas très complexe), pour sommer modulo 5 (je vois pas trop pourquoi, mais je connais pas ton problème) pour que ça tienne en mémoire sans générer de fichier intermédiaire nb_sino pourra pas dépasser 5 à priori au vu de ta configuration (faudra tester pour 6 ou 7), sinon, il faudra passer par l’écriture de fichiers temporaires, et c'est ce qui est coûteux en temps.  
 
A+,


Message édité par gilou le 28-02-2012 à 02:12:49

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2128643
gilou
Modérateur
Modzilla
Posté le 28-02-2012 à 11:17:43  profilanswer
 

Notes que la valeur de découpage lors de la génération des bootstraps, frame_size = 800; est maintenant en pixels et non plus en octet.  
Si la valeur de 800 octets a une signification importante, passer frame_size à 200 (si architecture en 32 bits) ou 100 (si 64 bits).
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2128837
Mourfizbak
Posté le 29-02-2012 à 11:14:16  profilanswer
 

Bonjour,
 
Gilou >> Je vous remercie beaucoup pour le code. J'ai eu un peu de mal à le comprendre, mais c'est nettement plus ingénieux que ma façon de procéder !Néanmoins, je préfère conserver mon code que je maîtrise parfaitement, car malgré mes efforts je ne suis vraiment pas bon en programmation ^^.
 
Je me permet de reposter sur ce forum car j'ai besoin d'optimiser davantage mon programme.
J'ai donc tenté de passer les sous-sinogrammes originaux dans des tableaux de pointeurs et de traiter l'ensemble du problème dans les mémoires volatiles, sans écrire les sous-sinogrammes bootstrap sur le disque dur. Après deux jours d'acharnement, je suis complètement bloqué, je n'obtient qu'une "erreur de segmentation".
 
Je souhaite savoir si la méthode que je suis est bonne et s'il est utile de persévérer dans cette voie, ou si je vais dans le mur !  :heink:  
 
merci d'avance !  :)  
 
Voici mon code (il peut paraître long mais au final beaucoup de petits blocs sont répétés 5 fois (pour les 5 sous-sinogrammes originaux), de ce fait le coeur du code est relativement court)
 
 

Code :
  1. int main(){
  2. // sched_getaffinity();
  3.    // demarrer_chrono();
  4. char nom[20] ;
  5. char nom1[20] ;
  6. char nom2[20] ;
  7. char nom3[20] ;
  8. char nom4[20] ;
  9. char nom5[20] ;
  10. char chaine[800] ;
  11. if(chaine==NULL)
  12. {
  13.  fprintf(stderr, "program exit\n" );
  14.  exit(EXIT_FAILURE) ;
  15. }
  16. char* chaine2 = (char*) malloc (sizeof(signed int)) ; //lecture entier par entier
  17. FILE* lire = NULL ;
  18. FILE* ecrire = NULL ;
  19. FILE* subsinoboot1 = NULL ;
  20. FILE* subsinoboot2 = NULL ;
  21. FILE* subsinoboot3 = NULL ;
  22. FILE* subsinoboot4 = NULL ;
  23. FILE* subsinoboot5 = NULL ;
  24. FILE* sino = NULL ;
  25. FILE* subsino1 = NULL ;
  26. FILE* subsino2 = NULL ;
  27. FILE* subsino3 = NULL ;
  28. FILE* subsino4 = NULL ;
  29. FILE* subsino5 = NULL ;
  30. int nb_ss_originaux , nb_ss_bootstrap , nb_sino ;
  31. long unsigned int sz_subsino , l ;
  32. int i , j , k , nb_al ;
  33. int nbsinocomplet ;
  34. float var ;
  35. signed long int val ;
  36. int test_fread ;
  37. int *tab_subsino1;
  38. int *tab_subsino2;
  39. int *tab_subsino3;
  40. int *tab_subsino4;
  41. int *tab_subsino5;
  42. int *tab_subsinotempo;
  43. int *tab_subsinoboot1;
  44. int *tab_subsinoboot2;
  45. int *tab_subsinoboot3;
  46. int *tab_subsinoboot4;
  47. int *tab_subsinoboot5;
  48. int *tab_sinoboot;
  49. test_fread = 0;
  50. nb_ss_originaux = 5;
  51. printf("Le nombre de sous-sinogrammes originaux est fixé à 5.\n" ) ;
  52. printf("Combien de sinogrammes bootstraps voulez-vous obtenir?\n" ) ;
  53. scanf("%d",&nb_sino) ; /* == B' ;*/
  54. nb_ss_bootstrap = nb_ss_originaux * nb_sino;
  55. printf("%d sous-sinogrammes bootstrap seront utilises \n",nb_ss_bootstrap);
  56. lire=fopen("subsino1.s","rb" ) ;
  57. if (lire == NULL)
  58.     {
  59. printf("subsino1.s : ouverture impossible\n" );
  60.         exit(0);
  61.     }
  62. test_fread = fseek(lire,0,SEEK_END) ;
  63. if (test_fread != 0)
  64.     {
  65. printf("fread sur lire impossible\n" );
  66.         exit(0);
  67.     }
  68. sz_subsino=ftell(lire) ;
  69.  printf("sz_subsino = %lu \n",sz_subsino);
  70. rewind(lire) ;
  71. fclose(lire) ;
  72.  printf("fclose lire ok\n" );
  73.  i=0 ;
  74.  nbsinocomplet=0 ;
  75. /*initialisation*/
  76. init_tabptr(tab_subsino1,sz_subsino+1);
  77. init_tabptr(tab_subsino2,sz_subsino+1);
  78. init_tabptr(tab_subsino3,sz_subsino+1);
  79. init_tabptr(tab_subsino4,sz_subsino+1);
  80. init_tabptr(tab_subsino5,sz_subsino+1);
  81. /*initialisation*/
  82. init_tabptr(tab_subsinoboot1,sz_subsino+1);
  83. init_tabptr(tab_subsinoboot2,sz_subsino+1);
  84. init_tabptr(tab_subsinoboot3,sz_subsino+1);
  85. init_tabptr(tab_subsinoboot4,sz_subsino+1);
  86. init_tabptr(tab_subsinoboot5,sz_subsino+1);
  87.  printf("initialisations ok\n" );
  88. /***********************************************************************************/
  89. /* Allocation mémoire des sous-sinogrammes originaux : */
  90. subsino1=fopen("subsino1.s","rb" ) ;
  91. fseek(subsino1, 0L, SEEK_SET); /*replace le curseur au début du fichier*/
  92. tab_subsino1 = malloc(sz_subsino); /*allocation de l'espace mémoire (dans la RAM) pour le pointeur vers le subsino1*/
  93. test_fread = fread (tab_subsino1, 1, sz_subsino, subsino1); /*lecture de sz_subsino éléments de taille unitaire = 1 dans le fichier subsino1.s et rangement dans le fichier tab_subsino*/
  94. fclose(subsino1);
  95. if (tab_subsino1 == NULL || test_fread == 0) /*Si l'allocation mémoire a échoué*/
  96.     {
  97. printf("Echec de l'allocation mémoire pour tab_subsino1" );
  98.         exit(0); /*On arrête immédiatement le programme*/
  99.     }
  100. subsino2=fopen("subsino2.s","rb" ) ;
  101. fseek(subsino2, 0L, SEEK_SET);
  102. tab_subsino2 = malloc(sz_subsino);
  103. test_fread = fread (tab_subsino2, 1, sz_subsino, subsino2);
  104. fclose(subsino2);
  105. if (tab_subsino2 == NULL || test_fread == 0)
  106.     {
  107. printf("Echec de l'allocation mémoire pour tab_subsino1" );
  108.         exit(0);
  109.     }
  110. subsino3=fopen("subsino3.s","rb" ) ;
  111. fseek(subsino3, 0L, SEEK_SET);
  112. tab_subsino3 = malloc(sz_subsino);
  113. test_fread = fread (tab_subsino3, 1, sz_subsino, subsino3);
  114. fclose(subsino3);
  115. if (tab_subsino3 == NULL || test_fread == 0)
  116.     {
  117. printf("Echec de l'allocation mémoire pour tab_subsino1" );
  118.         exit(0);
  119.     }
  120. subsino4=fopen("subsino4.s","rb" ) ;
  121. fseek(subsino4, 0L, SEEK_SET);
  122. tab_subsino4 = malloc(sz_subsino);
  123. test_fread = fread (tab_subsino4, 1, sz_subsino, subsino4);
  124. fclose(subsino4);
  125. if (tab_subsino4 == NULL || test_fread == 0)
  126.     {
  127. printf("Echec de l'allocation mémoire pour tab_subsino1" );
  128.         exit(0);
  129.     }
  130. subsino5=fopen("subsino5.s","rb" ) ;
  131. fseek(subsino5, 0L, SEEK_SET);
  132. tab_subsino5 = malloc(sz_subsino);
  133. test_fread = fread (tab_subsino5, 1, sz_subsino, subsino5);
  134. fclose(subsino5);
  135. if (tab_subsino5 == NULL || test_fread == 0)
  136.     {
  137. printf("Echec de l'allocation mémoire pour tab_subsino1" );
  138.         exit(0);
  139.     }
  140. /***********************************************************************************/
  141. // #pragma omp for /*optimisation multi-thread*/
  142.  l=0 ;
  143.  k=0 ;
  144.  while(l<sz_subsino){
  145.   nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  146.   if(nb_al=1){tab_subsinotempo = tab_subsino1;}
  147.   if(nb_al=2){tab_subsinotempo = tab_subsino2;}
  148.   if(nb_al=3){tab_subsinotempo = tab_subsino3;}
  149.   if(nb_al=4){tab_subsinotempo = tab_subsino4;}
  150.   if(nb_al=5){tab_subsinotempo = tab_subsino5;}
  151.   for(k ; k<k+800 ; k++){
  152.   tab_subsinotempo[k] = tab_subsinoboot1[k];
  153.   } // for
  154.   l = l + 800;
  155.  } // while
  156.  l=0 ;
  157.  k=0 ;
  158.  while(l<sz_subsino){
  159.   nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  160.   if(nb_al=1){tab_subsinotempo = tab_subsino1;}
  161.   if(nb_al=2){tab_subsinotempo = tab_subsino2;}
  162.   if(nb_al=3){tab_subsinotempo = tab_subsino3;}
  163.   if(nb_al=4){tab_subsinotempo = tab_subsino4;}
  164.   if(nb_al=5){tab_subsinotempo = tab_subsino5;}
  165.   for(k ; k<k+800 ; k++){
  166.   tab_subsinotempo[k] = tab_subsinoboot2[k];
  167.   } // for
  168.   l = l + 800;
  169.  } // while
  170.  l=0 ;
  171.  k=0 ;
  172.  while(l<sz_subsino){
  173.   nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  174.   if(nb_al=1){tab_subsinotempo = tab_subsino1;}
  175.   if(nb_al=2){tab_subsinotempo = tab_subsino2;}
  176.   if(nb_al=3){tab_subsinotempo = tab_subsino3;}
  177.   if(nb_al=4){tab_subsinotempo = tab_subsino4;}
  178.   if(nb_al=5){tab_subsinotempo = tab_subsino5;}
  179.   for(k ; k<k+800 ; k++){
  180.   tab_subsinotempo[k] = tab_subsinoboot3[k];
  181.   } // for
  182.   l = l + 800;
  183.  } // while
  184.  l=0 ;
  185.  k=0 ;
  186.  while(l<sz_subsino){
  187.   nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  188.   if(nb_al=1){tab_subsinotempo = tab_subsino1;}
  189.   if(nb_al=2){tab_subsinotempo = tab_subsino2;}
  190.   if(nb_al=3){tab_subsinotempo = tab_subsino3;}
  191.   if(nb_al=4){tab_subsinotempo = tab_subsino4;}
  192.   if(nb_al=5){tab_subsinotempo = tab_subsino5;}
  193.   for(k ; k<k+800 ; k++){
  194.   tab_subsinotempo[k] = tab_subsinoboot4[k];
  195.   } // for
  196.   l = l + 800;
  197.  } // while
  198.  l=0 ;
  199.  k=0 ;
  200.  while(l<sz_subsino){
  201.   nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  202.   if(nb_al=1){tab_subsinotempo = tab_subsino1;}
  203.   if(nb_al=2){tab_subsinotempo = tab_subsino2;}
  204.   if(nb_al=3){tab_subsinotempo = tab_subsino3;}
  205.   if(nb_al=4){tab_subsinotempo = tab_subsino4;}
  206.   if(nb_al=5){tab_subsinotempo = tab_subsino5;}
  207.   for(k ; k<k+800 ; k++){
  208.   tab_subsinotempo[k] = tab_subsinoboot5[k];
  209.   } // for
  210.   l = l + 800;
  211.  } // while
  212. if (sino = NULL)
  213.      {
  214.         printf("Impossible d'ouvrir le fichier" );
  215.      }
  216.  printf("Création du sinogramme complet ok : flag 1.1\n" );
  217.  /*ouverture du sinogramme complet de sortie*/
  218.  sprintf(nom,"sino_complet%d.s",nbsinocomplet+1); /*création du sinogramme complet (vide)*/
  219.  printf("\ncréation du fichier de sortie (%s)\n",nom);
  220.  sino = fopen(nom,"w" );
  221. tab_sinoboot = malloc(sz_subsino); /*allocation mémoire (RAM) pour le pointeur vers le sinogramme bootstrap complet*/
  222.   printf("malloc sino ok : flag 1.4\n" );
  223. if (tab_sinoboot == NULL)
  224.     {
  225. printf("Echec de l'allocation mémoire pour tab_sinoboot" );
  226.         exit(0);
  227.     }
  228.  k=0 ;
  229. for (k = 0 ; k < sz_subsino/sizeof(int) ; k++) {
  230.     tab_sinoboot[k] = tab_subsinoboot1[k] + tab_subsinoboot2[k] + tab_subsinoboot3[k] + tab_subsinoboot4[k] + tab_subsinoboot5[k]; /*somme pixel par pixel (dans la RAM) via les pointeurs sur les tableaux 2D des sinogrammes*/
  231. }
  232.  k=0 ;
  233. fwrite(tab_sinoboot, 1, sz_subsino, sino); /*ecriture de sz_subsino éléments de taille 1 du tableau tab_sino vers le fichier binaire du sinogramme bootstrap complet sino.*/
  234. fclose(sino);
  235. free(tab_subsinoboot1); /*libération de la mémoire*/
  236. free(tab_subsinoboot2);
  237. free(tab_subsinoboot3);
  238. free(tab_subsinoboot4);
  239. free(tab_subsinoboot5);
  240. free(tab_sinoboot);
  241. free(tab_subsino1);
  242. free(tab_subsino2);
  243. free(tab_subsino3);
  244. free(tab_subsino4);
  245. free(tab_subsino5);
  246.  nbsinocomplet++ ;
  247. //  for (k=0 ; k<nb_ssboot_par_somme ; k++){
  248.  // printf("les subsinogrammes bootstrap ont été supprimé avec succès\n" ) ;
  249. // } /*for sur i => tous les ss_bootstrap sont créés*/
  250. // printf("\nla création de sub-sinogrammes bootstraps est terminée\n" ) ;
  251.    // stop_chrono();
  252. } /*main*/


Message édité par Mourfizbak le 29-02-2012 à 11:18:30
n°2128877
gilou
Modérateur
Modzilla
Posté le 29-02-2012 à 12:27:06  profilanswer
 

Bonjour, pas de problème, c'est juste que mon code m'est plus lisible que le tien (je préfère faire des allocations dynamiques, car on peut écrire du code plus générique que le recopier en changeant un indice), mais je vois que tu en as saisi le principe.
 

Code :
  1. l=0 ;
  2. k=0 ;
  3. while(l < sz_subsino) {
  4.  nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  5.  if(nb_al=1){tab_subsinotempo = tab_subsino1;}
  6.  if(nb_al=2){tab_subsinotempo = tab_subsino2;}
  7.  if(nb_al=3){tab_subsinotempo = tab_subsino3;}
  8.  if(nb_al=4){tab_subsinotempo = tab_subsino4;}
  9.  if(nb_al=5){tab_subsinotempo = tab_subsino5;}
  10.  for(k ; k<k+800 ; k++){
  11.  tab_subsinotempo[k] = tab_subsinoboot2[k];
  12.  } // for
  13.  l = l + 800;
  14. } // while


trop de pb ici, en particulier le k<k+800 qui fait que tu as une boucle qui ne s’arrêtera jamais
un autre pb est que  
C'est toujours le même pb
la boucle intérieure  

Citation :

for(k ; k<k+800 ; k++){
  tab_subsinotempo[k] = tab_subsinobootX[k];
  } // for


 
c'est incompatible avec avec la boucle extérieure

Citation :

while(l<sz_subsino){
 
 l += 800;
}


parce que sz_subsino est compté en octet et que tes pointeurs sont sur des entiers, et donc qu'on se déplace de 4 ou 8 octets (selon que tu es en 32 ou 64 bits) à chaque tab_subsinotempo[k] = tab_subsinobootX[k];
 
Donc déjà pour corriger cela:

Code :
  1. l=0 ;
  2. k=0 ;
  3. while(l < sz_subsino/sizeof(int)) {
  4.  nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  5.         switch(nb_al) {
  6.         case 1: tab_subsinotempo = tab_subsino1; break;
  7.         case 2: tab_subsinotempo = tab_subsino2; break;
  8.         case 3: tab_subsinotempo = tab_subsino3; break;
  9.         case 4: tab_subsinotempo = tab_subsino4; break;
  10.         case 5: tab_subsinotempo = tab_subsino5; break;
  11.         }
  12.  for(k ; k<l+800 ; k++){
  13.  tab_subsinotempo[k] = tab_subsinoboot2[k];
  14.  } // for
  15.  l = l + 800;
  16. } // while


 
qui dans un 2eme temps peut s'écrire

Code :
  1. l=0 ;
  2. while(l < sz_subsino/sizeof(int)) {
  3.  nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  4.         switch(nb_al) {
  5.         case 1: tab_subsinotempo = tab_subsino1; break;
  6.         case 2: tab_subsinotempo = tab_subsino2; break;
  7.         case 3: tab_subsinotempo = tab_subsino3; break;
  8.         case 4: tab_subsinotempo = tab_subsino4; break;
  9.         case 5: tab_subsinotempo = tab_subsino5; break;
  10.         }
  11.  for(k=0 ; k<800 ; k++){
  12.  tab_subsinotempo[l+k] = tab_subsinoboot2[l+k];
  13.  } // for
  14.  l = l + 800;
  15. } // while


 
qui dans un 3eme temps peut s'écrire plus efficacement (copie en une seule fois d'une zone mémoire de 800 ints au lieu de 800 copies int par int)

Code :
  1. l=0 ;
  2. while(l < sz_subsino/sizeof(int)) {
  3.  nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  4.         switch(nb_al) {
  5.         case 1: tab_subsinotempo = tab_subsino1; break;
  6.         case 2: tab_subsinotempo = tab_subsino2; break;
  7.         case 3: tab_subsinotempo = tab_subsino3; break;
  8.         case 4: tab_subsinotempo = tab_subsino4; break;
  9.         case 5: tab_subsinotempo = tab_subsino5; break;
  10.         }
  11.         memcpy(tab_subsinotempo+l, tab_subsinoboot2+l, 800*sizeof(int));
  12.  l = l + 800;
  13. } // while


 
Mais néanmoins, il y a un pb qui subsiste: si sz_subsino/sizeof(int) n'est pas un multiple de 800, le dernier tour de boucle va dépasser les bornes du tableau.
Il faut corriger cela:
 

Code :
  1. l=0 ;
  2. while(sz_subsino/sizeof(int) - l >  800) {
  3.  nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  4.         switch(nb_al) {
  5.         case 1: tab_subsinotempo = tab_subsino1; break;
  6.         case 2: tab_subsinotempo = tab_subsino2; break;
  7.         case 3: tab_subsinotempo = tab_subsino3; break;
  8.         case 4: tab_subsinotempo = tab_subsino4; break;
  9.         case 5: tab_subsinotempo = tab_subsino5; break;
  10.         }
  11.         memcpy(tab_subsinotempo+l, tab_subsinoboot2+l, 800*sizeof(int));
  12.  l = l + 800;
  13. } // while
  14.         nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  15.         switch(nb_al) {
  16.         case 1: tab_subsinotempo = tab_subsino1; break;
  17.         case 2: tab_subsinotempo = tab_subsino2; break;
  18.         case 3: tab_subsinotempo = tab_subsino3; break;
  19.         case 4: tab_subsinotempo = tab_subsino4; break;
  20.         case 5: tab_subsinotempo = tab_subsino5; break;
  21.         }
  22.         memcpy(tab_subsinotempo+l, tab_subsinoboot2+l, (sz_subsino/sizeof(int) - l)*sizeof(int));


 
Notes que j'ai gardé la valeur 800, mais elle est et éventuellement à remplacer par 200 ou 100 (selon que tu es en 32 ou 64 bits) si tu veux garder la même taille en octets de la zone copiée à chaque fois.
Bon, j'ai pas été voir plus loin que ces pbs évidents à une première lecture, si après correction aux divers endroits ou ce code apparait, ça marche toujours pas, j'irais voir le reste.
A+,


Message édité par gilou le 29-02-2012 à 12:38:36

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2128889
Mourfizbak
Posté le 29-02-2012 à 13:13:12  profilanswer
 

Merci encore une fois pour toutes ces corrections. Je n'avais absolument pas vu ces problèmes :-/
 
J'ai cherché un moyen de faire ce que memcpy fait, sans y parvenir...content de connaître enfin ce "memcpy" !!
 
Concernant la valeur 800, elle correspond en fait à une ligne (de 800 pixels) d'un sinogramme. Ainsi, normalement, sz_subsino est toujours un multiple de 800, mais il est bon de le vérifier comme vous le proposez, on ne sait jamais !
 
Je continue de travailler sur les modifications, merci encore :)


Message édité par Mourfizbak le 29-02-2012 à 13:13:45
n°2128897
gilou
Modérateur
Modzilla
Posté le 29-02-2012 à 13:49:46  profilanswer
 

Si le fichier contient un multiple de 800 pixels, alors effectivement, ça explique pourquoi le code marchait sans pépin.
J'avais fait des essais de mon code avec le nombre premier 16 411 comme nb total de pixels dans un fichier de données, cette valeur étant parfaite pour des tests avec un fichier plus gros que 16384 (la première puissance de 2 supérieure à 10k) et ou on ne veut pas un artefact causé par un diviseur.
Gardez la valeur 800 avec ce code, puisque maintenant, c'est bien une ligne qui est copiée à la fois (avant, avec une copie a l'octet, c'était un quart ou un 8e de ligne qui l'était)
 
A+,


Message édité par gilou le 29-02-2012 à 13:51:36

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2129005
Mourfizbak
Posté le 01-03-2012 à 09:47:05  profilanswer
 

Bonjour,
 
Rappel pour vous éviter de relire tout le topic :
 
Je souhaite traiter de lourds fichiers binaires (subsino1 ... subsino5), correspondant à des images, de taille sz_subsino.
 

Code :
  1. tab_subsino1 = malloc(sz_subsino);
  2. tab_subsinoboot1 = malloc(sz_subsino);
  3. test_fread = fread (tab_subsino1, 1, sz_subsino, subsino1);


 
Mon soucis actuel est de tirer aléatoirement avec remise parmis ces cinq fichiers un ensemble de 800 pixels, les stocker dans un autre fichier binaire (tab_subsinoboot1), et recommencer jusqu'à obtenir un fichier tab_subsinoboot1 de taille sz_subsino.
 
Il y avait plusieurs autres bugs (assez stupides de ma part d'ailleurs  :whistle: ), mais maintenant le programme compile...et me renvoit un fichier de la bonne taille mais rempli de 0 !
 

Code :
  1. l=0 ;
  2.  k=0 ;
  3.  while(l < sz_subsino/sizeof(int)) { // car sz_subsino est compté en octet alors que les pointeurs pointent sur des entires => /sizeof(int)
  4.   nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  5.    switch(nb_al) { // choix aléatoire du sous-sinogramme original dans lequel on prend la ligne
  6.     case 1: tab_subsinotempo = tab_subsino1; break;
  7.     case 2: tab_subsinotempo = tab_subsino2; break;
  8.     case 3: tab_subsinotempo = tab_subsino3; break;
  9.     case 4: tab_subsinotempo = tab_subsino4; break;
  10.     case 5: tab_subsinotempo = tab_subsino5; break;
  11.    } // switch
  12. for (k=0;k<5000;k++){
  13.   if(tab_subsinotempo[k]!=0){
  14.  printf("flag 2 " );
  15.   }
  16. }
  17.            memcpy(tab_subsinotempo+l, tab_subsinoboot1+l, 800*sizeof(int)); // void *memcpy(void *dest,void *src,int longueur); avec la longueur donnée en octets (!)
  18.  l = l + 800;
  19.  } // while
  20. k=0;
  21. for (k=0;k<5000;k++){
  22.   if(tab_subsinoboot1[k]!=0){
  23.  printf("flag 3 " );
  24.   }
  25. }


 
Ayant vérifié avant le while que tab_subsinotempo était vide, j'obtiens pleins de "flag 2" (tab_subsinotempo n'est donc plus vide) mais aucun "flag 3" (la copie a échouée, tab_subsino1 est toujours vide). J'ai tenté avec une boucle plutôt qu'avec le memcpy, le résultat est identique...Je ne comprends pas où est le problème, il s'agit simplement d'une copie bête et méchante.
 
J'ai aussi un doute sur le l = l + 800, que je tranformerai bien en l = l + 800*sizeof(int)...
Merci d'avance ! :)


Message édité par Mourfizbak le 01-03-2012 à 11:07:06

---------------
Dans le doute, reboot, et si ça rate, formate !
n°2129086
gilou
Modérateur
Modzilla
Posté le 01-03-2012 à 12:28:02  profilanswer
 

Citation :

memcpy(tab_subsinotempo+l, tab_subsinoboot1+l, 800*sizeof(int)); // void *memcpy(void *dest,void *src,int longueur); avec la longueur donnée en octets (!)


 
C'était pourtant écrit: void *dest,void *src et on fait l'inverse :o  
Comme c'était faux dans votre code initial (tab_subsinotempo[k] = tab_subsinoboot2[k];) j'ai bêtement adapté sans faire attention
Il faut donc faire:
memcpy(tab_subsinoboot1+l, tab_subsinotempo+l, 800*sizeof(int));
 
le l = l+800 est bon, il ne faut pas y toucher
On a besoin de l en pixel, car l'addition tab_subsinoboot1+l est une addition de pointeur sur un int, donc déplace en mémoire à l'adresse tab_subsinoboot1+l*sizeof(int)
et on se déplace de 800 pixels à la fois.
 
Note: en y réfléchissant, on peut se passer des tab_subsinotempo:
Pour l'exemple donné hier:
 

Code :
  1. l=0 ;
  2. while(l < sz_subsino/sizeof(int)) {
  3. nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  4.         switch(nb_al) {
  5.         case 1: memcpy(tab_subsinoboot2+l, tab_subsino1+l, 800*sizeof(int)); break;
  6.         case 2: memcpy(tab_subsinoboot2+l, tab_subsino2+l, 800*sizeof(int)); break;
  7.         case 3: memcpy(tab_subsinoboot2+l, tab_subsino3+l, 800*sizeof(int)); break;
  8.         case 4: memcpy(tab_subsinoboot2+l, tab_subsino4+l, 800*sizeof(int)); break;
  9.         case 5: memcpy(tab_subsinoboot2+l, tab_subsino5+l, 800*sizeof(int)); break;
  10.         }
  11. l += 800;
  12. } // while


 
Bon, c'est juste une question de style, car on y gagne pas grand chose (une assignation de pointeur à chaque tour de boucle)
Noter aussi que si vous aviez assigné les tab_subsino1...tab_subsino5 dans une table tab_susino de 6 elements (avec le premier vide, si vous voulez une correspondance tab_subsino1 -> tab_subsino[1]...tab_subsino5 -> tab_subsino[5]) ce code se simplifierait en
 

Code :
  1. l=0 ;
  2. while(l < sz_subsino/sizeof(int)) {
  3.    nb_al=genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  4.    memcpy(tab_subsinoboot2+l, tab_subsino[nb_al]+l, 800*sizeof(int));
  5.    l += 800;
  6. } // while


et si vous procédiez de même avec une table tab_subsinoboot à 6 éléments
vous pourriez arriver à générer vos tab_subsinoboot1...tab_subsinoboot5 comme tab_subsinoboot[1]...tab_subsinoboot[5] avec

Code :
  1. for (j = 1; j < 6; ++j) {
  2.    l=0 ;
  3.    while(l < sz_subsino/sizeof(int)) {
  4.       nb_al = genrand_real2()*nb_ss_originaux+1 ; /*printf("%d\n",nb_al)*/
  5.       memcpy(tab_subsinoboot[j]+l, tab_subsino[nb_al]+l, 800*sizeof(int));
  6.       l += 800;
  7.    } // while
  8. }


 
A+,
 
P.S. Le virus de la grippe qui sévissait depuis une semaine dans mon entourage familial m'a finalement rattrapé, ce pourquoi je risque d'être un peu moins réactif aujourd'hui.


Message édité par gilou le 01-03-2012 à 12:31:25

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2129087
Mourfizbak
Posté le 01-03-2012 à 12:47:29  profilanswer
 

Bonjour !
 
Plus de 5h pour essayer de déboguer ce programme et je n'ai même pas pensé à vérifier que je copiais bien de la source vers le destinataire... :cry:  
 
Toujours est-il que maintenant cela marche parfaitement !Le temps d'exécution unitaire est passé de 900s avec le programme original à 8,7s maintenant !
 
Je vais prendre en compte vos idées de modifications, qui clarifient énormément le code. Je n'aurais jamais pensé à voir les choses sous cet angle.
 
Merci encore pour votre aide précieuse, et soignez votre grippe !


---------------
Dans le doute, reboot, et si ça rate, formate !
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Optimisation et multi-thread en C

 

Sujets relatifs
[C#] WCF Routing et WIFPHP->C# Besoin de conversion svp
Compilation parser XML pour intégration à un code Cintégrer .lib dans un projet C# (VS Express 2010)
[SQL] Optimisation de requête sqlbesoin d'aide en C
C++ : Jeu Damier (aide)Programmation en C
programme de VR sur le net (multi-plateforme)vb6 + data environement + requetes multi paramètres
Plus de sujets relatifs à : Optimisation et multi-thread en C


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR