为什么访问threadprivate变量会导致分段错误?

Matteeeo

我正在修改使用openmp库的现有Fortran代码。此代码的原始版本可完美并行运行。

当在多线程运行期间访问某个变量时,我会遇到分段错误(我通过在代码中设置标志来验证)。该数组定义为可分配的,然后定义为threadprivate,然后分配,而在原始版本中,它不是可分配的,并且其大小会立即设置。由于得到了我的工作计划,我修改了这部分。

这是重现该错误的基本代码。有罪的变量是一个名为“ var”的数组。

program testparallel
  use omp_lib
  implicit none
  integer :: thread_id, thread_num
  integer :: i,N
  integer,dimension(:),allocatable,save :: var

  !$omp threadprivate(var)

  N = 20
  allocate(var(5))

  !$omp parallel default(shared) private(thread_id)

  thread_id  = omp_get_thread_num()
  thread_num = omp_get_num_threads()
  write(*,*)'Parallel execution on ',thread_num, ' Threads'

  !$omp do

  do i=1,N
    var = 0
    write(*,*) thread_id,i
  end do

  !$omp end do
  !$omp end parallel

end program testparallel

这就是原始代码的结构方式,我没有直接修改这部分。var在循环内初始化,根据输入,其值稍后将由其他例程使用。

这是我获得的错误回溯:

 Parallel execution on            2  Threads
           0           1
           0           2
 Parallel execution on            2  Threads
           0           3
           0           4
           0           5

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
           0           6

Backtrace for this error:
           0           7
           0           8
           0           9
           0          10
#0  0x7F0149194697
#1  0x7F0149194CDE
#2  0x7F014824E33F
#3  0x400FB2 in MAIN__._omp_fn.0 at testparallel.F90:?
#4  0x7F0148C693C4
#5  0x7F01485ECDD4
#6  0x7F0148315F6C
#7  0xFFFFFFFFFFFFFFFF

如果我没有将var定义为可分配的,而是直接定义var的大小(如原始代码),则不会发生segfault。如果在将其设置为threadprivate之前进行分配,则会收到编译错误。

如何避免此错误,但将var保持可分配状态(这是必需的)?

编辑:我更正了原始代码的描述。

吉尔斯

您的问题来自于这样一个事实,尽管您var声明了可分配数组,但该数组threadprivate仅分配在代码的非并行部分中。因此,一旦进入并行段,只有主线程才能安全地访问该阵列。

一个非常简单的解决方法是将数组分配(以及随后的取消分配)包含在这样的parallel部分中:

!$omp parallel
allocate(var(5))
!$omp end parallel

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么与pthread链接会导致分段错误?

为什么glibc的fclose(NULL)会导致分段错误而不是返回错误?

为什么同时链接sdl2和udev会导致分段错误?

为什么以联合方式访问指针会导致分段错误?

为什么变量分配中的空格会导致Bash错误?

为什么用fast_executemany = True调用cursor.executemany()会导致分段错误?

为什么取消引用内存别名区域的C程序会导致分段错误?

为什么堆栈推送会导致分段错误?

为什么动态的字符串指针数组会导致分段错误?

为什么将项目添加到链表会导致分段错误?

为什么可选链接会导致重叠的访问错误?

为什么继承会导致共享内存分段错误?

为什么释放内存会导致分段错误?

为什么与I / O相关的设置会导致分段错误?

为什么此代码会导致分段错误

为什么使用atoi命令行参数会导致分段错误

为什么会导致错误?

尝试在循环中访问数组元素会导致分段错误,为什么?

为什么strlen会导致C中的分段错误?

为什么mov rax,cr0会导致nasm 64位中的分段错误

为什么命令行参数声明会导致分段错误

为什么这个 AVX 内在会导致“分段错误”,而不是 GCC?

为什么使用 paho.mqtt.c 发送此消息会导致分段错误?

为什么此代码会导致访问错误?

为什么声明长度为 INT_MAX 的 int 数组会导致分段错误?

访问结构数组会导致分段错误

为什么在传递给函数后访问指针会导致分段错误?

为什么这个双变量会导致分段错误?

为什么以下会导致分段错误?