Language agnostic 阵列的OpenMP线程部分是只读的

Language agnostic 阵列的OpenMP线程部分是只读的,language-agnostic,openmp,Language Agnostic,Openmp,这是在F90中,但问题适用于任何支持OpenMP的语言。对于需要多个存储阵列进行时间集成的模拟代码,构造数据的典型方法是(目前为二维): 然后会用如下内容更新: DO J = 1, jmax DO I = 1, imax vars(I,J,2) = func(vars(:,:,1)) END DO END DO 根据我的经验,OpenMP实际上不会并行化这些循环,因为它认为vars不是线程安全的。但对于程序员来说,显然是这样 让我们假设在进一步的实际情况下,使vars线程成为本

这是在F90中,但问题适用于任何支持OpenMP的语言。对于需要多个存储阵列进行时间集成的模拟代码,构造数据的典型方法是(目前为二维):

然后会用如下内容更新:

DO J = 1, jmax
  DO I = 1, imax
    vars(I,J,2) = func(vars(:,:,1))
  END DO
END DO
根据我的经验,OpenMP实际上不会并行化这些循环,因为它认为
vars
不是线程安全的。但对于程序员来说,显然是这样

让我们假设在进一步的实际情况下,使
vars
线程成为本地线程将非常昂贵,无法将数据复制到其中


那么,有没有一种方法可以温和地提示(又称强制)OpenMP不要锁定
vars
,因为它可能没有发现线程依赖性问题,但实际上没有?我知道有很多方法可以告诉它某些东西不是线程安全的,需要锁定,但是有没有一种方法可以在不为每个线程创建副本的情况下指定相反的值?

看起来你把OpenMP误认为是自动并行化。我不知道有任何OpenMP实现会执行数据锁定,除非通过引入
临界
部分或
原子
语句(或在带有
缩减
子句的并行区域末尾)明确告诉我。OpenMP编译器不会检查代码是否存在可能的数据依赖关系,并阻止您并行运行-这完全由您决定。如果您想进行不受保护的并发访问,您可以这样做,而且启用OpenMP的编译器不会阻止您这样做。以下代码将始终生成一个并行区域,并将外部循环分布在团队中的线程之间:

!$OMP PARALLEL DO PRIVATE(I)
DO J = 1, jmax
  DO I = 1, imax
    vars(I,J,2) = func(vars(:,:,1))
  END DO
END DO
!$OMP END PARALLEL DO
另一方面,大多数编译器中的内置自动并行程序都非常保守和谨慎,如果没有程序员的明确提示,通常不会并行处理像您这样的案例。这些提示通常以特定于编译器的指令的形式(在Fortran中格式化为注释或在C/C++中格式化为pragmas)。例如,“英特尔Fortran”支持
!DEC$PARALLEL
指令,提示它忽略该指令后面的循环中假定的数据依赖关系:

!DEC$ PARALLEL
DO J = 1, jmax
  DO I = 1, imax
    vars(I,J,2) = func(vars(:,:,1))
  END DO
END DO
许多编译器重用其OpenMP实现和运行库以实现自动并行化功能,因此生成的可执行文件的工作通常由OpenMP环境变量控制,如
OMP\u NUM\u THREADS


如果并行OpenMP程序的运行速度低于预期,则还有许多其他原因,主要与错误共享、缓存破坏、TLB破坏、内存带宽限制、NUMA系统上的非本地内存访问、对共享变量使用非临时加载/存储有关,等等。因此,看起来OpenMP is可能会执行自动数据锁定,但它不会。

看起来您将OpenMP误认为是自动并行。我不知道有任何OpenMP实现会执行数据锁定,除非通过引入
临界
部分或
原子
语句(或在带有
缩减
子句的并行区域末尾)明确告诉我。OpenMP编译器不会检查代码是否存在可能的数据依赖关系,并阻止您并行运行-这完全由您决定。如果您想进行不受保护的并发访问,您可以这样做,而且启用OpenMP的编译器不会阻止您这样做。以下代码将始终生成一个并行区域,并将外部循环分布在团队中的线程之间:

!$OMP PARALLEL DO PRIVATE(I)
DO J = 1, jmax
  DO I = 1, imax
    vars(I,J,2) = func(vars(:,:,1))
  END DO
END DO
!$OMP END PARALLEL DO
另一方面,大多数编译器中的内置自动并行程序都非常保守和谨慎,如果没有程序员的明确提示,通常不会并行处理像您这样的案例。这些提示通常以特定于编译器的指令的形式(在Fortran中格式化为注释或在C/C++中格式化为pragmas)。例如,“英特尔Fortran”支持
!DEC$PARALLEL
指令,提示它忽略该指令后面的循环中假定的数据依赖关系:

!DEC$ PARALLEL
DO J = 1, jmax
  DO I = 1, imax
    vars(I,J,2) = func(vars(:,:,1))
  END DO
END DO
许多编译器重用其OpenMP实现和运行库以实现自动并行化功能,因此生成的可执行文件的工作通常由OpenMP环境变量控制,如
OMP\u NUM\u THREADS

如果并行OpenMP程序的运行速度低于预期,则还有许多其他原因,主要与错误共享、缓存破坏、TLB破坏、内存带宽限制、NUMA系统上的非本地内存访问、对共享变量使用非临时加载/存储有关,所以看起来OpenMP执行自动数据锁定,但实际上并没有