Je travaille sur la parallélisation d’un code en utilisant OpenMP avec 3 types de threads et pas 2 comme d’habitude.Je devrais avoir un thread master d’application, un thread master et des threads workers.
Le thread de gestion des applications gérera le graphique des tâches de l’application (c.-à-d. il indiquera quelles tâches sont prêtes à exécuter et les mettra dans la file d’attente) le thread master lira la file d’attente et dès qu’une tâche est prête, il regardera si un thread worker est disponible pour l’exécuter, et enfin les workers qui accomplissent les tâches assignées par le maître.
Pour ce faire, j’ai implémenté une sous-routine qui exécute 3 tâches (3 boucles).J’ai aussi un diagramme de séquence à suivre :
subroutine management_3_tasks(tasklist_GRAD,ww,pas,cpt ,nb_element,cpt1,dt,dx,p_element,u_prime,u_prime_moins,u_prime_plus,&
&taux,grad_x_u,grad_t_u,grad_x_f,grad_t_f,ax_plus,ax_moins,ux_plus,ux_moins,sm,flux,tab0,tab)
INTEGER ::i,j,k,ff,pas
INTEGER,intent(inout)::cpt,cpt1,nb_element,ww
real*8 :: dt,dx
integer ,allocatable, dimension(:),intent(inout) ::p_element
REAL*8 ,allocatable, dimension(:),intent(inout) :: u_prime,u_prime_moins, u_prime_plus,taux,grad_x_u,&
&grad_t_u,grad_t_f,grad_x_f,flux,sm
real*8,allocatable,dimension(:),intent(inout) :: ax_plus,ax_moins,ux_moins,ux_plus
REAL*8 ,allocatable, dimension(:,:),intent(inout) ::tab0,tab
type(tcb)::self
!OpenMP variables
integer::num_thread,nthreads
integer, external :: OMP_GET_THREAD_NUM, OMP_GET_NUM_THREADS
type(tcb),dimension(20)::tasklist_GRAD,tasks_ready_master
!Variables pour gestion des threads
integer,allocatable,dimension(:)::threads_list !list containing the numbers of the threads workers
integer,dimension(100)::threads_list_all !liste containing the numbers of the threads workers in order according to the tasks
integer,dimension(3)::threads_list_part1 ! 3 first tasks
!=======================================================================================================================================================
!$OMP PARALLEL PRIVATE(num_thread) &
!$OMP SHARED(tasklist_GRAD,threads_list,threads_list_all,tasks_ready_master) &
!$OMP SHARED(threads_list_part1,nthreads)
num_thread=OMP_GET_THREAD_NUM() ! rank of the thread
nthreads=OMP_GET_NUM_THREADS() ! number of threads
!Thread Application Master (number 1)
if (num_thread==1) then
do ff=1,3 ! 3 tâches
if (associated(tasklist_GRAD(ff)%f_ptr) .eqv. .true. ) then ! Si tâche attribuée
tasks_ready_master(ff) = tasklist_GRAD(ff) ! égalité de pointeurs
tasks_ready_master(ff)%state=STATE_READY
end if
end do
end if
!$OMP BARRIER
!Thread Master (numero 0)
if (num_thread==0) then
allocate(threads_list(nthreads-2)) ! list of the workers
do ff=1,nthreads-2
threads_list(ff)=ff+1 ! 2,3,..,number of threads-2
end do
do ff=1,3,nthreads-2
if (tasks_ready_master(ff)%state==STATE_READY) then
threads_list_all(ff:ff+nthreads-3)=threads_list(:)
end if
end do
threads_list_part1=threads_list_all(1:3) ! 3 tasks
deallocate(threads_list)
end if
!$OMP BARRIER
!Threads workers
do ff=1,3
if (num_thread==threads_list_part1(ff)) then
!$OMP TASK
call tasks_ready_master(ff)%f_ptr(self,ww,pas,cpt ,nb_element,cpt1,dt,dx,p_element,u_prime,u_prime_moins,&
&u_prime_plus,taux,grad_x_u,grad_t_u,grad_x_f,grad_t_f,ax_plus,ax_moins,ux_plus,ux_moins,sm,flux,tab0,tab)
tasks_ready_master(ff)%state=STATE_RUNNING
!$OMP END TASK
end if
end do
!$OMP BARRIER
!Thread Master (numero 0)
if (num_thread==0) then
do ff=1,3
if (tasks_ready_master(ff)%state==STATE_RUNNING) then
tasklist_GRAD(ff)%state=STATE_RUNNING
end if
end do
end if
!$OMP END PARALLEL
end subroutine management_3_tasks
chaque case de cette liste pointe sur une procédure.
type:: tcb !task control block
procedure(my_interface),NOPASS,pointer:: f_ptr => null() !the function pointer
integer :: state !the task state
end type tcb
Je voudrais savoir pourquoi le temps d’exécution du code parallélisé (4 threads) est supérieur à celui du code séquentiel (1 thread).J’ai aussi des valeurs étranges comme si les calculs étaient faits plusieurs fois. Je ne peux pas poster le code entier qui est calme longtemps c’est pourquoi je vous ai donné le lien vers mon git.Vous pouvez trouver à la fois le code séquentiel et le code parallèle.
C'est la première fois que je poste une question sur ce forum. Excusez-moi si ma question n'est pas bien formulée.
- Edité par HakimOueslati1 14 juin 2021 à 14:13:21
avant d'essayer de trouver une solution, pourrais-tu nous dire ce que tu entends pas "plus long" ? Quelle est la durée d'exécution séquentielle, et quelle est la durée d'exécution parallèle ? Quelles routines utilises-tu pour mesurer le temps d'exécution ? (cette dernière question à plus d'importance qu'on ne le crois ...).
Avez-vous entendu parler de Julia ? Laissez-vous tenter ...
avant d'essayer de trouver une solution, pourrais-tu nous dire ce que tu entends pas "plus long" ? Quelle est la durée d'exécution séquentielle, et quelle est la durée d'exécution parallèle ? Quelles routines utilises-tu pour mesurer le temps d'exécution ? (cette dernière question à plus d'importance qu'on ne le crois ...).
Salut,
En ce qui concerne le temps d'exécution du code séquentiel, j'obtiens 20 secondes. Pour le code parallélisé, le temps est estimé à 80 secondes voire 100 secondes. Pour le code séquentiel, j'ai utilisé CPU_TIME et system_clock. Pour le code parallélisé, j'ai utilisé omp_get_wtime.
J'ai peut-être une idée : lorsqu'on utilise des tâches, il faut les lancer à partir d'un seul thread. Comme tu as pu le remarquer, une région parallèle (qui ici correspond au corps de ta routine) est exécuté par tous les threads en même temps (d'où le fait que tu testes ton numéro de thread). En particulier, tes tâches parallèles sont toutes lancées autant de fois que tu as des threads. Par exemple, si tu as 3 tâches parallèles et 4 threads, tu en lances 3x4=12 alors que tu ne voudrais en lancer que 3 (du coup tu refais le calcul pour rien). Je pense qu'il faut encadrer la zone de code où tu lances tes tâches par un environnement
!$OMP SINGLE
...
!$OMP END SINGLE
qui indique que la portion de code que tu vas exécuter ne dois l'être qu'à partir d'un seul thread (mais qui ne sera pas forcément le 0 ou le 1). Peut-être suffit-il simplement de re-tester le numéro de thread sur lequel tu es.
Avez-vous entendu parler de Julia ? Laissez-vous tenter ...
Temps d'exécution du code parallélisé
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Avez-vous entendu parler de Julia ? Laissez-vous tenter ...
Avez-vous entendu parler de Julia ? Laissez-vous tenter ...