2016-07-15 2 views
0

Я хочу сравнить некоторый код Fortran с OpenMP-потоками с критическим разделом. Чтобы имитировать реалистичную среду, я попытался создать некоторую нагрузку до этого критического раздела.Код занимает гораздо больше времени, чтобы закончить более чем с 1 потоком

!Kompileraufruf: gfortran -fopenmp -o minExample.x minExample.f90 

    PROGRAM minExample 
    USE omp_lib 
    IMPLICIT NONE 
    INTEGER      :: n_chars, real_alloced 
    INTEGER      :: nx,ny,nz,ix,iy,iz, idx 
    INTEGER      :: nthreads, lasteinstellung,i 
    INTEGER, PARAMETER    :: dp = kind(1.0d0) 
    REAL (KIND = dp)    :: j 
    CHARACTER(LEN=32)    :: arg 

    nx    = 2 
    ny    = 2 
    nz    = 2 
    lasteinstellung= 10000 
    CALL getarg(1, arg) 
    READ(arg,*) nthreads 
    CALL OMP_SET_NUM_THREADS(nthreads) 
!$omp parallel 
!$omp master 
    nthreads=omp_get_num_threads() 
!$omp end master 
!$omp end parallel 
    WRITE(*,*) "Running OpenMP benchmark on ",nthreads," thread(s)" 

    n_chars = 0 
    idx = 0 
!$omp parallel do default(none) collapse(3) & 
!$omp shared(nx,ny,nz,n_chars) & 
!$omp private(ix,iy,iz, idx) & 
!$omp private(lasteinstellung,j) !& 
    DO iz=-nz,nz 
     DO iy=-ny,ny 
      DO ix=-nx,nx 
!     WRITE(*,*) ix,iy,iz 
      j = 0.0d0 
      DO i=1,lasteinstellung 
       j = j + real(i) 
      END DO 
!$omp critical 
      n_chars = n_chars + 1    
      idx = n_chars      
!$omp end critical 
      END DO 
     END DO 
    END DO 
    END PROGRAM 

Я составил этот код gfortran -fopenmp -o test.x test.f90 и выполнил его с time ./test.x THREAD Выполнение этого кода дает какое-то странное поведение в зависимости от потока подсчета (набор с omp_set_num_threads): по сравнению с одним потоком (6 мс) исполнение с большим количеством нитей стоит намного больше времени (2 потока: 16000мс, 4 потока: 9000мс) на моей многоядерной машине. Что может вызывать такое поведение? Есть ли лучший (но еще простой) способ генерации нагрузки без использования некоторых кеш-эффектов или связанных с ними вещей?

изменить: странное поведение: если у меня есть запись во вложенных циклах, скорость выполнения резко увеличивается с помощью двух потоков. Если его прокомментировать, выполнение с 2 или 3 потоками длится вечно (запись показывает очень медленное приращение переменных цикла) ... но не с 1 или 4 потоками. Я пробовал этот код и на другой многоядерной машине. Там требуется 1 и 3 потока навсегда, но не для 2 или 4 потоков.

+3

Добро пожаловать в StackOverflow. Если у вас есть проблема с кодом, вы должны создать пример Minimal, Complete и Verifiable http://stackoverflow.com/help/mcve. Что мы можем попытаться запустить сами. –

+0

Имеет ли эта «другая машина» гиперпоточность? [Нитки, работающие на двух логических ядрах одного и того же физического ядра ЦП, могут общаться гораздо быстрее, чем на отдельных физических ядрах) (http://stackoverflow.com/questions/32979067/what-will-be-used-for-data-exchange -between-потоки-которые-выполнение-на-один-Core-Wi/32981256). Я не знаю Fortran, поэтому я даже не попытался пропустить код, чтобы узнать, может ли это быть частью объяснения. –

ответ

2

Если код, который вы показываете, действительно завершен, вы не указали определение loadSet в параллельном разделе, в котором оно находится private. Не определено и петля

    DO i=1,loadSet 
        j = j + real(i) 
       END DO 

может принимать абсолютно произвольное количество итераций.

Если значение определено где-то раньше в коде, который вы не показываете, вы, вероятно, хотите firstprivate вместо private.

+0

Определена переменная. Проблема заключалась в том, что я заявлял об этом как о закрытом. Благодаря! –

 Смежные вопросы

  • Нет связанных вопросов^_^