I am seeking advice about some OpenMP code I have written. (THis is my first foray into OpenMP programming.) I would like to know if (a) It is legal code (It currently compiles and gives the expected answers) and (b) If my handling of the 4 threads is optimal.
I have a data array define as
real, allocatable :: d(:,:)
in a module; then created as:
allocate d(d(n,n)) later, and actually used as an array of length len x len
As it happens, the most time consuming part of the calculation can be run as 4 parallel threads which take identical times (to within a few ms) and use the same amount of memory. Each thread produces just 3 integers as its final result and these are stored in an array howmany(15). (The first 3 elements of howmany() hold other data.) I have written the following code to handle this situation for computers with >=4 , 3, 2 and 1 core(s).
! Allow program to modify the number of threads call omp_set_dynamic(.true.) ! How many cores to use? i = omp_get_max_threads() NumThreads = min0(4, i) if(len <= 50) NumThreads = 1 ! <= 50 not worth the overheads call omp_set_num_threads(NumThreads) ! Now the parallel code if(NumThreads == 1) then ! No multicore processor available, so 1 thread at a time. call count_clusters_OMP(1,d,n,len,lower,upper, .true.,NumThreads,ierr) call count_clusters_OMP(2,d,n,len,lower,upper, .true.,NumThreads,ierr) call count_clusters_OMP(3,d,n,len,lower,upper, .true.,NumThreads,ierr) call count_clusters_OMP(4,d,n,len,lower,upper, .true.,NumThreads,ierr) ! 2 cores else if(NumThreads == 2 .or. NumThreads == 3) then ! 1st 2 calculations !$OMP PARALLEL SECTIONS COPYIN(d, howmany, maxval, minval, n, len) !$OMP SECTION call count_clusters_OMP(1,d,n,len,lower,upper,.true.,NumThreads,ierr) !$OMP SECTION call count_clusters_OMP(2,d,n,len,lower,upper,.false.,NumThreads,ierr) !$OMP END PARALLEL SECTIONS ! Second set !$OMP PARALLEL SECTIONS COPYIN(d, howmany, maxval, minval, n, len) !$OMP SECTION call count_clusters_OMP(3,d,n,len,lower,upper,.true.,NumThreads,ierr) !$OMP SECTION call count_clusters_OMP(4,d,n,len,lower,upper,.false.,NumThreads,ierr) !$OMP END PARALLEL SECTIONS ! 4 cores (or more) else if(NumThreads == 4) then !$OMP PARALLEL SECTIONS COPYIN(d, howmany, maxval, minval, n, len) !$OMP SECTION call count_clusters_OMP(1,d,n,len,lower,upper,.true.,NumThreads,ierr) !$OMP SECTION call count_clusters_OMP(2,d,n,len,lower,upper,.false.,NumThreads,ierr) !$OMP SECTION call count_clusters_OMP(3,d,n,len,lower,upper,.false.,NumThreads,ierr) !$OMP SECTION call count_clusters_OMP(4,d,n,len,lower,upper,.false.,NumThreads,ierr) !$OMP END PARALLEL SECTIONS endif
(lower, upper, minval and maxval are scalars.)
A colleague of mine has criticised this code on 2 grounds:
- It is not legal Fortran.
- I should not manage the threads as I do but let the software do this.
Can I solicit an expert opinion please?
With thanks
Chris G