Introduction au Parallélisme

Cours

Notes de cours au format PDF.

Transparents au format PDF.

Exemples données en cours

Listing 1: hello.c

#include <stdio.h>
#include <omp.h>

main()
{
   int nthreads, tid;

   /* omp_set_num_threads(8); */
   /* Fork a team of threads giving them their own copies of variable */
#pragma omp parallel private(nthreads, tid)
   {
      /* obtain and print thread id */
      tid = omp_get_thread_num();
      printf("Hello World from thread = %d\n", tid);

      /* Only master thread does this */
      if (tid == 0) 
      {
         nthreads = omp_get_num_threads();
         printf("Number of threads = %d from tid=%d\n", nthreads, tid);
      }
   } /* All threads join master thread and terminate */

}

Listing 2: hello.f

      PROGRAM HELLO
      INTEGER NTHREADS, TID, OMP_GET_NUM_THREADS
      INTEGER OMP_GET_THREAD_NUM

C     Fork a team of threads giving them their own copies of variables
!$OMP PARALLEL PRIVATE(NTHREADS, TID)

C     Obtain an dprint thread id
      TID = OMP_GET_THREAD_NUM()
      PRINT *, 'Hello World from thread =', TID

C     Only master thread does this
      IF (TID .EQ. 0) THEN
         NTHREADS = OMP_GET_NUM_THREADS()
         PRINT *, 'Number of threads = ', NTHREADS
      ENDIF

C     All threads join master thread and disband
!$OMP END PARALLEL

      END

Listing 3: hello2.c

#include <stdio.h>
#include <omp.h>

main()
{
   int nthreads, tid;

   /* omp_set_num_threads(8); */
   /* Fork a team of threads giving them their own copies of variable */
#pragma omp parallel private(nthreads, tid)
   {
      /* obtain and print thread id */
      tid = omp_get_thread_num();
      printf("Hello World from thread = %d\n", tid);

      /* Only one thread does this */
         nthreads = omp_get_num_threads();
#pragma omp single
         printf("Number of threads = %d from tid=%d\n", nthreads, tid);
   } /* All threads join master thread and terminate */

}

Listing 4: vecteuradd.c

#include <stdio.h>
#include <omp.h>
#include <math.h>
#define CHUNK 100
#define N     100000

main ()  
{

int i, n, chunk, tid;
float a[N], b[N], c[N];

/* Some initializations */
for (i=0; i < N; i++)
  a[i] = b[i] = i * 1.0;
n = N;
chunk = CHUNK;

#pragma omp parallel shared(a,b,c,n,chunk) private(i,tid)
  {

  tid = omp_get_thread_num();
  printf("Hello World from thread = %d\n", tid);

  #pragma omp for schedule(dynamic,chunk) nowait
  for (i=0; i < n; i++)
  {
    c[i] = sqrt(a[i]) + cos(b[i]);
    printf("thread = %d loop %d\n", tid, i);
  }

  }  /* end of parallel section */

}

Listing 5: vecteuradd.f

      PROGRAM VEC_ADD_DO

      INTEGER N, CHUNK, I, TID
      PARAMETER (N=1000) 
      PARAMETER (CHUNK=1) 
      REAL A(N), B(N), C(N)
      INTEGER OMP_GET_THREAD_NUM

!     Some initializations
      DO I = 1, N
        A(I) = I * 1.0
        B(I) = A(I)
      ENDDO

!$OMP PARALLEL SHARED(A,B,C) PRIVATE(I,tid)

      tid = omp_get_thread_num()

!$OMP DO SCHEDULE(dynamic,CHUNK)
      DO I = 1, N
         C(I) = A(I) + B(I)
         write(*,*) 'Thread = ', tid, ' iteration = ', i
      ENDDO
!$OMP END DO  NOWAIT

C Tous les threads arrivent ici 
      write(*,*) 'Thread = ', tid, 'avant barriere'
!$OMP BARRIER
      write(*,*) 'Thread = ', tid, 'apres barriere'

!$OMP END PARALLEL

      END

Listing 6: vecteuradd2.c

#include <stdio.h>
#include <omp.h>
#include <math.h>
#define N     1000

main ()
{

int i, n, tid;
float a[N], b[N], c[N];

/* Some initializations */
for (i=0; i < N; i++)
  a[i] = b[i] = i * 1.0;
n = N;

#pragma omp parallel shared(a,b,c,n) private(i)
  {

  tid = omp_get_thread_num();
  printf("Hello World from thread = %d\n", tid);

  #pragma omp sections nowait
    {

      #pragma omp section
      {
         printf("In section 1: %d\n",tid);
         for (i=0; i < n/2; i++)
           c[i] = a[i] + b[i];
      }

      #pragma omp section
      {
         printf("In section 2: %d\n",tid);
         for (i=n/2; i < n; i++)
           c[i] = a[i] + b[i];
      }

    }  /* end of sections */
/*
    #pragma omp single
    {
       printf(" Le travail est termine (tid = %d)\n", tid);
    }
*/
  }  /* end of parallel section */

}

Listing 7: vecteuradd2.f

      PROGRAM VEC_ADD_SECTIONS

      INTEGER N, I
      PARAMETER (N=1000)
      REAL A(N), B(N), C(N)

!     Some initializations
      DO I = 1, N
        A(I) = I * 1.0
        B(I) = A(I)
      ENDDO

!$OMP PARALLEL SHARED(A,B,C,N), PRIVATE(I)

!$OMP SECTIONS

!$OMP SECTION
      DO I = 1, N/2
         C(I) = A(I) + B(I)
      ENDDO

!$OMP SECTION
      DO I = 1+N/2, N
         C(I) = A(I) + B(I)
      ENDDO

!$OMP END SECTIONS NOWAIT

!$OMP END PARALLEL

      END

Listing 8: vecteuradd3.c

#include <stdio.h>
#include <omp.h>
#define N       10
#define CHUNK   1

main ()  {

int i, n, chunk, tid;
float a[N], b[N], c[N];

/* Some initializations */
for (i=0; i < N; i++)
  a[i] = b[i] = i * 1.0;
n = N;
chunk = CHUNK;

#pragma omp parallel for \
   shared(a,b,c,n) private(i,tid) \
   schedule(static,chunk)
  for (i=0; i < n; i++)
  {
    tid = omp_get_thread_num();
    c[i] = a[i] + b[i];
    printf("thread = %d loop %d\n", tid, i);
  }

printf("toto\n");
}

Listing 9: vecteuradd3.f

      PROGRAM VECTOR_ADD

      INTEGER N, I, CHUNK
      PARAMETER (N=1000) 
      PARAMETER (CHUNK=100) 
      REAL A(N), B(N), C(N)

!     Some initializations
      DO I = 1, N
        A(I) = I * 1.0
        B(I) = A(I)
      ENDDO

!$OMP PARALLEL DO 
!$OMP& SHARED(A,B,C,N) PRIVATE(I) 
!$OMP& SCHEDULE(STATIC,CHUNK)

      DO I = 1, N
         C(I) = A(I) + B(I)
      ENDDO

!$OMP END PARALLEL DO

      END

Listing 10: reduction.c

#include <stdio.h>
#include <omp.h>

main ()  {

int   i, n, chunk, tid;
float a[100], b[100], result;
float c[10];
int maxthreads;
int currentthreads;

/* Some initializations */
n = 10;
chunk = 1;
result = 0.0;
for (i=0; i < n; i++)
  {
  a[i] = i * 1.0;
  b[i] =  1.0;
  }

maxthreads = omp_get_max_threads();
printf("maximum number of threads = %d\n", maxthreads);
/* omp_set_num_threads(8); */

currentthreads = omp_get_num_threads();
printf("nous sommes %d\n", currentthreads);


#pragma omp parallel default(shared) private(i,tid) 
{
  currentthreads = omp_get_num_threads();
  printf("nous sommes desormais %d\n", currentthreads);

  tid = omp_get_thread_num();

#pragma omp for schedule(static,chunk)\
   reduction(+:result)
  for (i=0; i < n; i++)
  {
    result = result + (a[i] * b[i]);
    printf("thread = %d loop %03d result %f\n", tid, i, result);
    c[tid] = result;
  }

  printf("c[%d] = %f, result = %f\n", tid, c[tid], result);
}

printf("tid = %d, c[%d] = %f\n", tid, tid, c[tid]);

printf("Final result= %f\n",result);

}

Listing 11: reduction.f

       PROGRAM DOT_PRODUCT

       INTEGER N, CHUNK, I
       PARAMETER (N=10)
       PARAMETER (CHUNK=1)
       REAL A(N), B(N), RESULT
       INTEGER TID, OMP_GET_THREAD_NUM

!      Some initializations

       DO I = 1, N
         A(I) = I * 1.0
         B(I) = I * 2.0
       ENDDO
       RESULT= 0.0

!$OMP  PARALLEL DO
!$OMP& DEFAULT(SHARED) PRIVATE(I)
!$OMP& SCHEDULE(STATIC,CHUNK)
!$OMP& REDUCTION(+:RESULT)

       DO I = 1, N
         tid = OMP_GET_THREAD_NUM()
         RESULT = RESULT + (A(I) * B(I))
         write (*,*) 'Thread=',tid,' RESULT = ',
     .                result, a(i)*b(i), a(i), b(i)
       ENDDO

!$OMP  END PARALLEL DO 

       PRINT *, 'Final Result= ', RESULT
       END