简体   繁体   English

ARPACK线程安全吗?

[英]Is ARPACK thread-safe?

Is it safe to use the ARPACK eigensolver from different threads at the same time from a program written in C? 从用C编写的程序中同时使用来自不同线程的ARPACK本解析器是否安全? Or, if ARPACK itself is not thread-safe, is there an API-compatible thread-safe implementation out there? 或者,如果ARPACK本身不是线程安全的,那么是否存在与API兼容的线程安全实现? A quick Google search didn't turn up anything useful, but given the fact that ARPACK is used heavily in large scientific calculations, I'd find it highly surprising to be the first one who needs a thread-safe sparse eigensolver. 一个快速的谷歌搜索没有发现任何有用的东西,但鉴于ARPACK在大型科学计算中被大量使用的事实,我发现成为第一个需要线程安全稀疏的本征解析器的人是非常令人惊讶的。

I'm not too familiar with Fortran, so I translated the ARPACK source code to C using f2c , and it seems that there are quite a few static variables. 我对Fortran不太熟悉,所以我使用f2c将ARPACK源代码翻译成C,似乎有很多静态变量。 Basically, all the local variables in the translated routines seem to be static, implying that the library itself is not thread-safe. 基本上,转换例程中的所有局部变量似乎都是静态的,这意味着库本身不是线程安全的。

I have converted ARPACK to C using f2c . 我已经使用f2c将ARPACK转换为C. Whenever you use f2c and you care about thread-safety you must use the -a switch. 每当你使用f2c并且你关心线程安全时,你必须使用-a开关。 This makes local variables have a utomatic storage, ie be stack based locals rather than statics which is the default. 这使得局部变量 utomatic存储,即可以基于堆栈的当地人,而不是静态这是默认的。

Even so, ARPACK itself is decidedly not threadsafe. 即便如此,ARPACK本身绝对不是线程安全的。 It uses a lot of common blocks (ie global variables) to preserve state between different calls to its functions. 它使用许多公共块(即全局变量)来保持对其函数的不同调用之间的状态。 If memory serves, it uses a reverse communication interface which tends to lead developers to using global variables. 如果内存服务,它使用反向通信接口,往往导致开发人员使用全局变量。 And of course ARPACK probably was written long before multi-threading was common. 当然,ARPACK可能是在多线程很常见之前编写的。

I ended up re-working the converted C code to systematically remove all the global variables. 我最终重新编译转换后的C代码以系统地删除所有全局变量。 I created a handful of C structs and gradually moved the global variables into these structs. 我创建了一些C结构,并逐渐将全局变量移动到这些结构中。 Finally I passed pointers to these structs to each function that needed access to those variables. 最后,我将指向这些结构的指针传递给需要访问这些变量的每个函数。 Although I could just have converted each global into a parameter wherever it was needed it was much cleaner to keep them all together, contained in structs. 虽然我可以将每个全局转换为一个参数,只要它需要它就可以将它们全部保持在一起,包含在结构中。

Essentially the idea is to convert global variables into local variables. 本质上,我们的想法是将全局变量转换为局部变量。

Fortran 77 does not support recursion, and hence a standard conforming compiler can allocate all variables in the data section of the program; Fortran 77不支持递归,因此符合标准的编译器可以在程序的数据部分中分配所有变量; in principle, neither a stack nor a heap is needed [1]. 原则上,既不需要堆栈也不需要堆栈[1]。

It might be that this is what f2c is doing, and if so, it might be that it's the f2c step that makes the program non thread-safe, rather than the program itself. 这可能是f2c正在做的事情,如果是这样,可能是f2c步骤使程序不是线程安全的,而不是程序本身。 Of course, as others have mentioned, check out for COMMON blocks as well. 当然,正如其他人提到的那样,请查看COMMON块。 EDIT : Also, check for explicit SAVE directives. 编辑 :另外,检查明确的SAVE指令。 SAVE means that the value of the variable should be retained between subsequent invocations of the procedure, similar to static in C. Now, allocating all procedure local data in the data section makes all variables implicitly SAVE, and unfortunately, there is a lot of old code that assumes this even though it's not guaranteed by the Fortran standard. SAVE意味着变量的值应该在过程的后续调用之间保留,类似于C中的静态。现在,在数据部分中分配所有过程本地数据会使所有变量隐式保存,不幸的是,有很多旧的即使Fortran标准无法保证,也会假设这一代码。 Such code, obviously, is not thread-safe. 显然,这样的代码不是线程安全的。 Wrt. WRT。 ARPACK specifically, I can't promise anything but ARPACK is generally well regarded and widely used so I'd be surprised if it suffered from these kinds of dusty-deck problems. 特别是ARPACK,我不能保证任何东西,但ARPACK通常被广泛使用和广泛使用,所以如果它遭受这些尘埃甲板问题我会感到惊讶。

Most modern Fortran compilers do use stack allocation. 大多数现代Fortran编译器都使用堆栈分配。 You might have better luck compiling ARPACK with, say, gfortran and the -frecursive option. 你可能有更好的运气编译ARPACK,比如gfortran和-frecursive选项。

EDIT : 编辑

[1] Not because it's more efficient, but because Fortran was originally designed before stacks and heaps were invented, and for some reason the standards committee wanted to retain the option to implement Fortran on hardware with neither stack nor heap support all the way up to Fortran 90. Actually, I'd guess that stacks are more efficient on todays heavily cache-dependent hardware rather than accessing procedure local data that is spread all over the data section. [1]不是因为它更有效,而是因为Fortran最初是在堆栈和堆之前设计的,并且由于某种原因,标准委员会希望保留在硬件上实现Fortran的选项,既没有堆栈也没有堆支持一直到Fortran 90.实际上,我猜测堆栈在当今高度依赖缓存的硬件上更有效,而不是访问遍布数据部分的过程本地数据。

ARPACK uses BLAC right? ARPACK使用BLAC吧? Then those libraries need to be thread safe too. 那些库也需要是线程安全的。 I believe your idea to check with f2c might not be a bullet proof way of telling if the Fortran code is thread safe, I would guess it also depends on the Fortran compiler and libraries. 我相信你用f2c检查你的想法可能不是告诉Fortran代码是否是线程安全的防弹方法,我猜它也取决于Fortran编译器和库。

I don't know what strategy f2c uses in translating Fortran. 我不知道f2c在翻译Fortran时使用了什么策略。 Since ARPACK is written in FORTRAN 77, the first thing to do is check for the presence of COMMON blocks. 由于ARPACK是在FORTRAN 77中编写的,因此首先要检查是否存在COMMON块。 These are global variables, and if used, the code is most likely not thread safe. 这些是全局变量,如果使用,代码很可能不是线程安全的。 The ARPACK webpage, http://www.caam.rice.edu/software/ARPACK/ , says that there is a parallel version -- it seems likely that that version is threadsafe. ARPACK网页http://www.caam.rice.edu/software/ARPACK/表示有一个并行版本 - 似乎该版本是线程安全的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM