【问题标题】:Is reading/writing to different elements of a module array thread-safe?读/写模块数组的不同元素是线程安全的吗?
【发布时间】:2017-06-27 20:50:20
【问题描述】:

只要程序不允许同时写入存储在模块中的共享数据结构的相同元素,它是否是线程安全的?我知道这是一个菜鸟问题,但在任何地方都找不到明确解决的问题。情况如下:

在程序开始时,数据被初始化并存储在模块级可分配数组 (FIELDVARS) 中,然后任何子程序都可以访问该数组,其中该模块被 USE 语句引用。

现在假设程序进入多线程和/或多核计算阶段,并且在重复多次同时调用子程序 (COMPUTE) 期间访问 FIELDVARS 以进行“读/写”操作。

一旦计算阶段完成,程序将返回单线程阶段,FIELDVARS 必须在后续子例程中使用 (POST)。但是,FIELDVARS 不能添加到 COMPUTEPOST 的输入参数中,因为它们是从闭源主程序调用的。因此,模块级数组用于在子程序之间传递addt'l数据。

假设FIELDVARSCOMPUTE 的设计使得每次调用COMPUTE 都可以访问FIELDVARS 的一组唯一元素,这些元素保证不同于任何其他调用,这样对相同元素的同时“写”操作就不会发生。例如:

[ 1, 2, 3, 4, 5,  6, 7, 8, 9, 10, ... ]  <-- FIELDVARS
  ^---call 1---^  ^---call 2---^  ...    <-- Each call to COMPUTE is guaranteed to access a specific set of elements of FIELDVARS.

问题:这种情况被认为是“线程安全”、“条件安全”还是“非线程安全”?如果不安全,具体的危险是什么?您建议如何处理?

其他相关细节:

  • 主程序控制线程。
  • 主程序源代码不可用,无法更改。
  • 主程序控制如何/何时调用COMPUTEPOST和其他子程序,以及可以传入哪些args。这就是为什么模块级数组用于在不同子程序之间传递数据的原因而不是 arg。

! DEMO MODULE W/ ALLOCATABLE INTEGER ARRAY
module DATA_MODULE
  integer, dimension(:), allocatable :: FIELDVARS  !<-- allocated/populated elsewhere, prior to calling COMPUTE
end module DATA_MODULE

! DEMO COMPUTE SUBROUTINE (THREADED PHASE W/ MULTIPLE SIMULTANEOUS CALLS)
subroutine COMPUTE(x, y, x_idx, y_idx, flag)
  use DATA_MODULE
  logical :: flag
  integer :: x,y,x_idx,y_idx                 !<-- different for every call to COMPUTE
  if (flag == .false.) then                  !<-- read data only
    ...
    x = FIELDVARS(x_idx)
    y = FIELDVARS(y_idx)
    ...
  else if (flag == .true.) then              !<-- write data
    ... 
    FIELDVARS(x_idx) = 0
    FIELDVARS(y_idx) = 0
    ...
  endif
end subroutine COMPUTE

【问题讨论】:

标签: multithreading fortran thread-safety


【解决方案1】:

这很好,许多程序都依赖于这一事实。在 OpenMP 中,您经常循环遍历数组,并且不同的线程可以轻松地处理内存中彼此靠近的元素,尤其是在分配给每个线程的块的边界上。

在现代 CPU 中,这不是问题。另见https://en.wikipedia.org/wiki/Cache_coherence

真正的问题是False sharing。两个或多个线程使用属于同一 chache 行的内存元素将竞争共享资源,并且可能非常慢。

【讨论】:

  • 感谢您提供额外的链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-15
  • 2018-01-08
  • 2017-05-14
  • 2019-04-23
相关资源
最近更新 更多