Tam*_*más 6 c fortran thread-safety arpack
从用C编写的程序中同时使用来自不同线程的ARPACK本征解析器是否安全?或者,如果ARPACK本身不是线程安全的,那么是否存在与API兼容的线程安全实现?一个快速的谷歌搜索没有发现任何有用的东西,但鉴于ARPACK在大型科学计算中被大量使用的事实,我发现成为第一个需要线程安全稀疏的本征解析器的人是非常令人惊讶的.
我对Fortran不太熟悉,所以我将ARPACK源代码翻译成C使用f2c
,似乎有很多静态变量.基本上,转换例程中的所有局部变量似乎都是静态的,这意味着库本身不是线程安全的.
Fortran 77 不支持递归,因此符合标准的编译器可以在程序的数据部分分配所有变量;原则上,既不需要栈也不需要堆[1]。
可能这就是 f2c 正在做的事情,如果是这样,则可能是 f2c 步骤而不是程序本身使程序成为非线程安全的。当然,正如其他人提到的,也请检查 COMMON 块。编辑:另外,检查显式的 SAVE 指令。SAVE 意味着变量的值应该在过程的后续调用之间保留,类似于 C 中的 static。现在,在数据段中分配所有过程本地数据使得所有变量隐式 SAVE,不幸的是,有很多旧的即使 Fortran 标准不保证这一点,代码也会假设这一点。显然,这样的代码不是线程安全的。沃特。具体来说,我不能保证任何东西,但 ARPACK 普遍受到好评并被广泛使用,所以如果它遇到这些灰尘甲板问题,我会感到惊讶。
大多数现代 Fortran 编译器都使用堆栈分配。您可能会更幸运地使用 gfortran 和 -frecursive 选项编译 ARPACK。
编辑:
[1] 不是因为它更高效,而是因为 Fortran 最初是在堆栈和堆发明之前设计的,并且出于某种原因,标准委员会希望保留在既不支持堆栈也不支持堆的硬件上实现 Fortran 的选项Fortran 90。实际上,我猜想在当今严重依赖缓存的硬件上堆栈比访问遍布整个数据部分的过程本地数据更有效。
我已经使用 ARPACK 转换为f2c
C。每当您使用f2c
并且关心线程安全时,您都必须使用该-a
开关。这使得局部变量具有自动存储,即基于堆栈的局部变量而不是默认的静态变量。
即便如此,ARPACK 本身也绝对不是线程安全的。它使用许多公共块(即全局变量)来保存对其函数的不同调用之间的状态。如果没记错的话,它使用反向通信接口,这往往会导致开发人员使用全局变量。当然,ARPACK 可能是在多线程普及之前很久就编写的。
我最终重新处理了转换后的 C 代码,系统地删除了所有全局变量。我创建了一些 C 结构体,并逐渐将全局变量移至这些结构体中。最后,我将指向这些结构的指针传递给需要访问这些变量的每个函数。尽管我可以在需要的地方将每个全局变量转换为参数,但将它们全部放在一起并包含在结构中要干净得多。
本质上,这个想法是将全局变量转换为局部变量。