[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.
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.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. ...-
-
Donne un ordre de grandeur de NB_IZOOM, qu'on sache un peu mieux ce qui se passe.
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. -
-
je ne sais pas ce que tu fais dans le redimensionnement, mais si ça fait appel à des fonctions système (new, open etc.) il est possible que les fonctions se marchent sur les pieds.
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. -
Je suis en train de voir ce que ça donne avec des threads. Bon j'ai des soucis intermédiaire comme par exemple stocker mon subname[NB_IZOOM][BUF_SIZE] dans une structure routine_arg (puisqu'on ne peut passer qu'un seul argument à un thread, je met tout dans une struct), mais ça pourrait être plus intéressant. Il me semble que les accès concurrents en lecture ne posent pas de problèmes, si ?
-
-
essai sans le wait(0). Le fork prend du temps tout de même !