Fortran 为什么访问threadprivate变量会导致分段错误?
我正在修改使用openmp库的现有Fortran代码。此代码的原始版本可以完美地并行工作 当在多线程运行期间访问某个变量时,我得到一个分段错误(我通过在代码中设置标志进行验证)。此数组定义为可分配,然后定义为threadprivate,然后再进行分配,而在原始版本中,它不是可分配的,其大小立即设置。由于我的工作计划,我修改了这一部分 下面是一段基本代码,它再现了错误。这里的负罪变量是一个名为“var”的数组 这或多或少是原始代码的结构,我没有直接修改这部分。var在循环中初始化,根据输入,其值稍后由其他例程使用 这是我得到的错误回溯:Fortran 为什么访问threadprivate变量会导致分段错误?,fortran,segmentation-fault,openmp,Fortran,Segmentation Fault,Openmp,我正在修改使用openmp库的现有Fortran代码。此代码的原始版本可以完美地并行工作 当在多线程运行期间访问某个变量时,我得到一个分段错误(我通过在代码中设置标志进行验证)。此数组定义为可分配,然后定义为threadprivate,然后再进行分配,而在原始版本中,它不是可分配的,其大小立即设置。由于我的工作计划,我修改了这一部分 下面是一段基本代码,它再现了错误。这里的负罪变量是一个名为“var”的数组 这或多或少是原始代码的结构,我没有直接修改这部分。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定义为可分配变量,而是定义其大小straighaway(如原始代码中所示),则不会发生segfault。如果在将其设置为threadprivate之前分配它,则会出现编译错误
我如何避免这个错误,但保持var是可分配的(这是必要的)
编辑:我更正了原始代码的描述。您的问题来自这样一个事实,即尽管您的可分配数组
var
声明为threadprivate
,但它只分配在代码的非并行部分。因此,一旦在并行段上,只有主线程可以安全地访问阵列
一个非常简单的修复方法是将数组分配(以及随后的取消分配)包含在并行
部分中,如下所示:
!$omp parallel
allocate(var(5))
!$omp end parallel
我假设您的计算机中有8个线程。您能将分配的从5增加到>8吗?同样的事情仍然发生在10个线程中。不,我的意思是,如果您将
allocate(var(5))
更改为allocate(var(20))
,您会得到同样的错误吗?是的,仍然是这样,非常感谢,我太依赖现有代码的结构了。
!$omp parallel
allocate(var(5))
!$omp end parallel