2013-09-30 4 views
1

Проблемы Я облицовка, как указано ниже:OpenMP вызов подпрограммы в потоках

module k 
    integer :: l,m 
end module k 

program p4 
    use k 
    integer :: i,j,omp_get_thread_num,cr 

    i = 2 
    j = 3 

    !$omp parallel num_threads(2) shared(l,m) private(i,j,cr) 
    cr = omp_get_thread_num() 
    if (cr == 0) goto 1111 
    call sub1(i) 
    write(*,*) l 
    goto 2222 
1111 call sub2(j) 
    write(*,*) m 
2222 continue 
    !$omp end parallel 
end program p4 

subroutine sub1(a) 
    use k 
    integer :: a 

    l = a**2 
    write(*,*) 'entered sub1' 
end subroutine sub1 

subroutine sub2(b) 
    use k 
    integer :: b 

    m = b**2 
    write(*,*) 'entered sub2' 
end subroutine sub2 

Я попытался параллелизовать серийный, (который после распараллеливания выглядит как написано выше). Я хочу, чтобы одна и та же операция выполнялась дважды. Так В идеале, я хочу выход быть

entered sub1 
4 
enterer sub2 
9 

но выход

entered sub2 
      0 
entered sub1 
    923239424 

Я новичок параллельного программирования (моя актуальная проблема более сложная версия одного я конспектированный). Может ли кто-нибудь указать на ошибки и предложить улучшения. Благодарности

+0

Согласовано с выше. То, что у вас есть, нечитаемо. Это Хаскелл? – Adam

+0

@ Адам: Haskell ?? Нет, очевидно, Фортран. Ключевые подсказки: «продолжить». –

+0

@IraBaxter ах да, я просто видел GOTO, тоже. Спасибо за совет. Возможно, я должен прекратить делать такую ​​хорошую работу, избегая как Фортрана, так и Хаскелла. – Adam

ответ

7

private OpenMP переменные не даны начальные значения, поэтому обе вызовы sub1 и sub2 сделаны со случайными значениями i и j. То, что вы (возможно) ищет это firstprivate вместо:

!$omp parallel num_threads(2) shared(l,m) private(cr) firstprivate(i,j) 
... 
!$omp end parallel 

firstprivate инициализирует каждый частный экземпляр со значением, что соответствующая переменная в главном потоке было на входе в параллельную область.

Btw, реализующий IF/THEN/ELSE/ENDIF с IF/GOTO/CONTINUE в Fortran 90 и более поздний, считается многими плохой стиль программирования. Вместо этого следует использовать разделы OpenMP:

!$omp parallel sections num_threads(2) shared(l,m) private(cr) firstprivate(i,j) 
    !$omp section 
    call sub1(i) 
    write(*,*) l 
    !$omp section 
    call sub2(j) 
    write(*,*) m 
!$omp end parallel sections 
+0

Не уверен, но, возможно, вам следует удалить раздел '! $ Omp end'. gfortran не распознает это, и он не находится в учебнике [this] (https://computing.llnl.gov/tutorials/openMP/#SECTIONS). –

+0

Вы правы - просто взглянули на стандарт. Я добавил их полностью механически. –

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