Я хочу сравнить некоторый код 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 потоков.
Добро пожаловать в StackOverflow. Если у вас есть проблема с кодом, вы должны создать пример Minimal, Complete и Verifiable http://stackoverflow.com/help/mcve. Что мы можем попытаться запустить сами. –
Имеет ли эта «другая машина» гиперпоточность? [Нитки, работающие на двух логических ядрах одного и того же физического ядра ЦП, могут общаться гораздо быстрее, чем на отдельных физических ядрах) (http://stackoverflow.com/questions/32979067/what-will-be-used-for-data-exchange -between-потоки-которые-выполнение-на-один-Core-Wi/32981256). Я не знаю Fortran, поэтому я даже не попытался пропустить код, чтобы узнать, может ли это быть частью объяснения. –