6

从用 C 编写的程序中同时使用来自不同线程的ARPACK eigensolver是否安全?或者,如果 ARPACK 本身不是线程安全的,那么是否有与 API 兼容的线程安全实现?快速的谷歌搜索并没有发现任何有用的东西,但鉴于 ARPACK 在大型科学计算中被大量使用,我会发现成为第一个需要线程安全稀疏特征求解器的人非常令人惊讶。

我对Fortran不太熟悉,所以我把ARPACK源代码翻译成C using f2c,貌似静态变量不少。基本上,翻译后的例程中的所有局部变量似乎都是静态的,这意味着库本身不是线程安全的。

4

4 回答 4

4

Fortran 77 不支持递归,因此符合标准的编译器可以在程序的数据部分分配所有变量;原则上,既不需要堆栈也不需要堆[1]。

可能这就是 f2c 正在做的事情,如果是这样,可能是 f2c 步骤使程序非线程安全,而不是程序本身。当然,正如其他人所提到的,也要检查 COMMON 块。编辑: 另外,检查明确的 SAVE 指令。SAVE 的意思是在程序的后续调用之间应该保留变量的值,类似于 C 中的 static即使 Fortran 标准不保证这一点的代码。显然,这样的代码不是线程安全的。写。特别是 ARPACK,我不能保证任何事情,但 ARPACK 通常受到好评并被广泛使用,所以如果它遇到这些尘土飞扬的问题,我会感到惊讶。

大多数现代 Fortran 编译器确实使用堆栈分配。使用 gfortran 和 -frecursive 选项编译 ARPACK 可能会更好。

编辑

[1] 不是因为它更高效,而是因为 Fortran 最初是在堆栈和堆发明之前设计的,出于某种原因,标准委员会希望保留在既不支持堆栈也不支持堆的硬件上实现 Fortran 的选项,直到Fortran 90。实际上,我猜堆栈在当今高度依赖缓存的硬件上比访问遍布数据部分的过程本地数据更有效。

于 2010-10-10T18:55:29.983 回答
4

我已经使用 ARPACK 将 ARPACK 转换为f2cC。每当您使用f2c并且关心线程安全时,都必须使用该-a开关。这使得局部变量具有自动存储,即基于堆栈的局部变量而不是默认的静态变量。

即便如此,ARPACK 本身绝对不是线程安全的。它使用许多公共块(即全局变量)来保存对其函数的不同调用之间的状态。如果记忆有用,它会使用反向通信接口,这往往会导致开发人员使用全局变量。当然,ARPACK 可能早在多线程普及之前就已经编写好了。

我最终重新处理了转换后的 C 代码,以系统地删除所有全局变量。我创建了一些 C 结构,并逐渐将全局变量移到这些结构中。最后,我将指向这些结构的指针传递给需要访问这些变量的每个函数。尽管我可以将每个全局变量转换为任何需要的参数,但将它们放在一起会更干净,包含在结构中。

本质上,这个想法是将全局变量转换为局部变量。

于 2011-08-07T11:19:23.683 回答
1

ARPACK 使用 BLAC 对吗?那么这些库也需要是线程安全的。我相信您使用 f2c 检查的想法可能不是判断 Fortran 代码是否是线程安全的防弹方法,我猜它也取决于 Fortran 编译器和库。

于 2010-10-08T09:29:45.580 回答
1

我不知道 f2c 在翻译 Fortran 时使用了什么策略。由于 ARPACK 是用 FORTRAN 77 编写的,所以首先要做的是检查 COMMON 块的存在。这些是全局变量,如果使用,代码很可能不是线程安全的。ARPACK 网页http://www.caam.rice.edu/software/ARPACK/说有一个并行版本——该版本似乎是线程安全的。

于 2010-10-08T13:04:44.070 回答