[C] Utiliser fork() correctement
Résolu
Sauvegarde2
Messages postés
219
Statut
Membre
-
Sauvegarde2 Messages postés 219 Statut Membre -
Sauvegarde2 Messages postés 219 Statut Membre -
Bonjour ou bonsoir,
Je travaille sur un programme de traitement d'image qui s'exécute en 8 secondes. Pour améliorer ce temps je souhaite introduire des forks, voici ce que ça donne :
J'ai respecté la structure que j'ai vu en faisant des recherches sur internet, pourtant mon programme est anormalement lent (en fait il se bloque sur la deuxième miniature).
Pouvez-vous m'aider et me dire ce qui ne va pas s'il vous plait ?
Context :
source[] étant un tableau de NB_IZOOM images,
pzoom[] la liste des pourcentage de réduction (zoom),
subname[] et subdir[] des chemins de fichiers,
geometry vaut ici "256x256", c'est la taille des tuiles que je désire.
resize() renvoie une image miniaturisée de la source à hauteur de pzoom,
crop() découpe la source en tuiles et les enregistre sur le disque.
Le wait(0) est ici pour empêcher le programme de découper l'image avant qu'elle ne soit créée. Cela limite aussi le nombre de fils à un seul.
Je travaille sur un programme de traitement d'image qui s'exécute en 8 secondes. Pour améliorer ce temps je souhaite introduire des forks, voici ce que ça donne :
for(i = 0 ; i < NB_IZOOM ; i++) { if(i > 0) { source[i] = resize(source[0], subname[i], pzoom[i]); } wait(0); pid = fork(); switch(pid) { case -1: perror("fork()"), exit(-1); case 0 : crop(source[i], subname[i], subdir[i], geometry); exit(0); default: break; } }
J'ai respecté la structure que j'ai vu en faisant des recherches sur internet, pourtant mon programme est anormalement lent (en fait il se bloque sur la deuxième miniature).
Pouvez-vous m'aider et me dire ce qui ne va pas s'il vous plait ?
Context :
source[] étant un tableau de NB_IZOOM images,
pzoom[] la liste des pourcentage de réduction (zoom),
subname[] et subdir[] des chemins de fichiers,
geometry vaut ici "256x256", c'est la taille des tuiles que je désire.
resize() renvoie une image miniaturisée de la source à hauteur de pzoom,
crop() découpe la source en tuiles et les enregistre sur le disque.
Le wait(0) est ici pour empêcher le programme de découper l'image avant qu'elle ne soit créée. Cela limite aussi le nombre de fils à un seul.
A voir également:
- [C] Utiliser fork() correctement
- Comment utiliser chromecast sur tv - Guide
- Utiliser iphone comme webcam - Guide
- Utiliser tablette comme deuxieme ecran - Guide
- Comment utiliser teamviewer - Guide
- Comment utiliser wetransfer - Guide
2 réponses
Déjà on sais maintenant que c'est le wait qui pose problème.
As tu lus le man de wait ? Je comprends qu'un enfant qui se termine correctement doit avoir un exit(2) ou exit(3). Peut être que comme tu retournes un exit(0), le wait détecte un problème ?
Tu peux aussi récupérer les retours de wait ainsi que le status (paramètre de wait() ) pour voir si quelques chose se passe mal.
Je pense que ton algorithme est mal pensé, faire un fork prend du temps car il faut dupliquer le processus, et là tu fait un fork à chaque itération que tu détruit ensuite, donc tu fais NB_IZOOM fork. Selon la valeur de NB_ZOOM, ça peut être très pénalisant.
Pour moi, la bonne façon de faire et ton script s'y prete bien, c'est de faire le fork avant le for et de couper ta boucle en deux.
As tu lus le man de wait ? Je comprends qu'un enfant qui se termine correctement doit avoir un exit(2) ou exit(3). Peut être que comme tu retournes un exit(0), le wait détecte un problème ?
Tu peux aussi récupérer les retours de wait ainsi que le status (paramètre de wait() ) pour voir si quelques chose se passe mal.
Je pense que ton algorithme est mal pensé, faire un fork prend du temps car il faut dupliquer le processus, et là tu fait un fork à chaque itération que tu détruit ensuite, donc tu fais NB_IZOOM fork. Selon la valeur de NB_ZOOM, ça peut être très pénalisant.
Pour moi, la bonne façon de faire et ton script s'y prete bien, c'est de faire le fork avant le for et de couper ta boucle en deux.
pid=fork(); if(pid==0) { for (i=0;i<NB_IZOOM/2;++i) { if(i!=0)source[i] = resize(source[0], subname[i], pzoom[i]); crop(source[i], subname[i], subdir[i], geometry); } exit(2); }else { for (i=NB_IZOOM/2;i<NB_IZOOM;++i) { source[i] = resize(source[0], subname[i], pzoom[i]); crop(source[i], subname[i], subdir[i], geometry); } } wait(0);// attend la fin de l'enfant pour être certain de ne pas avoir de problème de synchronisation dans la suite. ...
Ce que je vois : fork prend du temps à être fait, donc il faut vraiment que la boucle soit longue en calcul. 8s ça me parait exploitable, si tu passe bien la majorité du temps dans la boucle que tu donnes. Je pense que tu devrais descendre à 5s.
Je vois une autre cause possible au ralentissement : l'écriture sur disque. Il faut d'abord vérifier que ça ne soit pas ça qui prenne le plus de temps. Du coup en parallèle, peut être que les deux processus se marchent un peu sur les pieds pour écrire.
=> profilage ou test du programme en supprimant la fonction d'écriture.
Ou alors c'est le recopiage des données qui est long à cause de comme tu dit l'histoire du cache, en parallèle tu es obligé de faire pleins d'aller retour dans la RAM ce qui doit prendre du temps ? Après, il y a des méthodes d'optimisation pour aller plus vite, sinon il va falloir se contenter des 8s.