8

我有以下问题:Fortran90+ 中分配/解除分配语句的实际开销是多少?即,在一个循环内分配了几个中等大小的数组,比如

do i = 1, 1000
    allocate(tmp(20))
    tmp(1:20) = 1d0
    call foo(tmp)
    deallocate(tmp)
end do 

在这种情况下,是否值得根据最大大小分配单个工作数组?

4

2 回答 2

7

我发现紧密循环中的动态数组分配确实会减慢代码的执行速度,而 valgrind 显示很大比例的循环被mallocand占用free。所以如果foo是一个非常快速的函数,那么静态分配这个数组是值得的。通过使用valgrind的 callgrind 功能进行分析,很容易看到这种开销(可能值得减少问题的大小,因为分析的执行速度可能至少慢 10 倍)。

在 fortran 2008 中,此类问题有更好的解决方案。您可以在block结构中声明变量,其大小在运行时确定。这应该使编译器更容易在堆栈上分配变量。但是我没有亲自使用过它,我不确定哪些编译器支持它。

于 2012-07-05T01:28:55.443 回答
4

使用and 的开销与在 C 中使用 andALLOCATEDEALLOCATE开销相同。实际上,大多数 Fortran 编译器都将其实现为包装器,并增加了一些记录,这是所有 Fortran 90 数组所固有的。malloc()free()(DE)ALLOCATEmalloc()/free()

通常最好预先分配一个足够大的临时数组并在紧密循环中使用它,而不是不断地分配和释放内存。它还可以防止堆碎片化,这可能会导致稍后出现分配问题(非常罕见的情况,但它会发生,尤其是对于 32 位代码)。

于 2012-07-04T20:45:21.720 回答