首页 > 解决方案 > Double check locking in fortran with openmp

问题描述

So i have some code with a double checked locking solution for reading data files in multi threaded (with openmp) application, which looks something like:

logical, dimension(10,10) :: is_data_loaded
is_data_loaded=.false.

! Other code

subroutine load(i,j)
    integer,intent(in) :: i,j ! Indexes into array is_data_loaded
    if(is_data_loaded(i,j)) return
    !$OMP CRITICAL(load data)
        if(.not.is_data_loaded(i,j)) then
            call load_single_file(i,j)
            is_data_loaded(i,j) = .true.
        endif
    !$OMP END CRITICAL(load_data)
end subroutine 

Where I'm worried that if two threads get to the critical region at the same time (with the same i,j index) the second gets blocked by the first one entering the region but once the first finishes the second thread may start executing the critical block before seeing the updated is_data_loaded flag and thus we get into a problem with two threads updating the same data.

So firstly is this an issue with opemp critical blocks? I'm unsure of the semantics and whether the standard says something like "everything must be consistent across threads before the next thread runs in a critical block" or not. And if it is a problem, would just wrapping the read/writes to is_data_loaded in an omp atomic statement be sufficient?

标签: multithreadingfortranopenmp

解决方案


我认为代码是错误的,因为线程可能确实看不到is_data_loaded在另一个线程从该critical区域设置它之后的更新。虽然该critical区域将确保发生相应的内存刷新,但执行该区域的线程if(is_data_loaded(i,j)) return可能看不到更新,因为该语句可能仍会看到过时的数据。

我认为需要!$omp flush在之前添加if(is_data_loaded(i,j)) return以确保所有数据都已刷新并is_data_loaded(i,j)加载了最新数据。


推荐阅读