Parallel processing 如何在此Fortran代码中使用OpenMP正确地将lambdaeff数传递给内核?

Parallel processing 如何在此Fortran代码中使用OpenMP正确地将lambdaeff数传递给内核?,parallel-processing,fortran,Parallel Processing,Fortran,我正在尝试并行化一个代码,该代码计算两个整数nue和nut;然后使用这些数字计算另一个数值lambdaeff。我可以展示一个(愚蠢的)MWE(实际代码是1200行蒙特卡罗代码): 如果我按照指示使用并行do循环并行化代码,我不确定lambdaeff编号是否会正确传递到各个内核。我如何修改循环的最后一行以正确地将lambdaeff传递到cores?总结@Vadimir F、@PetrH和@Ian Bush的评论: 不要使用rand(),因为它不是线程安全的;改用 如果要使用OpenMP 有一个大

我正在尝试并行化一个代码,该代码计算两个整数
nue
nut
;然后使用这些数字计算另一个数值
lambdaeff
。我可以展示一个(愚蠢的)MWE(实际代码是1200行蒙特卡罗代码):


如果我按照指示使用并行
do
循环并行化代码,我不确定
lambdaeff
编号是否会正确传递到各个内核。我如何修改循环的最后一行以正确地将lambdaeff传递到cores?

总结@Vadimir F、@PetrH和@Ian Bush的评论:

  • 不要使用
    rand()
    ,因为它不是线程安全的;改用
  • 如果要使用OpenMP
  • 有一个大的,请查一下(后一个术语适用于这里)
编辑:


如果我有第二个变量
lnet=lnet nue+nut
,它应该由所有线程共享,比如
lambdaeff
,我应该如何修改reduce语句


您想使用OpenMP还是MPI?请澄清,它们是完全不同的东西。请在问题中包含代码。MWE将是有用的,不要使用
rand()
。当然,不要在任何并行代码中使用它,但通常也要避免使用它。对于蒙特卡罗,您需要一个可靠的经过测试的随机数生成器。对于OpenMP,您需要一些线程安全的东西。例如,在gfortran中实现的只是“g77提供的简单模生成器”,而在gfortran中实现的是使用非常好、快速的生成器和线程安全。但是,对于其他编译器,一般来说没有任何东西是可以保证的。使用专用库是很好的。请了解线程和内核之间的区别,这是您应该使用的前一个术语。但是要解决您的问题,您需要一个reduce语句-必须有一个重复的地方。如果我有第二个变量
lnet=lnet nue+nut
,它应该由所有线程共享,例如
lambdaeff
如何修改reduce语句?reduce语句的一般语法是:
reduce(:)
,所以只需将
lnet
添加到参数列表中即可。
Do n=1, 100
 nue=int(100*rand())
 nut=int(50*rand())
 lambdaeff=lambdaeff+(nue-nut)^2
end do
program main
  use, intrinsic :: omp_lib
  implicit none
  integer :: i, tid, nthreads
  integer :: nue, nut, lambdaeff = 0, lnet = 0
  real    :: r(2)

  ! Set number of threads
  nthreads = OMP_get_max_threads()
  write (*,*) "Using ", nthreads, "thread(s)"

  !$OMP PARALLEL NUM_THREADS(nthreads) PRIVATE(tid)
  ! Who am I?
  tid = OMP_get_thread_num()

  ! Reduction do loop
  !$OMP DO REDUCTION(+:lambdaeff,lnet) PRIVATE(nue,nut,r)
  do i = 1, 100
    call random_number(r)
    nue = int(100*r(1))
    nut = int(50*r(2))
    lambdaeff = lambdaeff + (nue-nut)**2
    lnet = lnet+(nue-nut)

  end do
  !$OMP END DO

  ! lambdaeff is same for all threads
  write (*,*) tid, lambdaeff, lnet

  !$OMP END PARALLEL

end program main