Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Optimization 为什么Fortran在';对于分配';或';对于"解除分配"';?_Optimization_Fortran_Intel Fortran - Fatal编程技术网

Optimization 为什么Fortran在';对于分配';或';对于"解除分配"';?

Optimization 为什么Fortran在';对于分配';或';对于"解除分配"';?,optimization,fortran,intel-fortran,Optimization,Fortran,Intel Fortran,我正试图优化我继承的一些Fortran代码。这是一个非常重复的代码,需要几天才能运行,我正在努力减少运行时间。根据VTune放大器的说法,在减少了一些函数和子例程的运行时间后,最新的瓶颈是\u释放和\u分配,特别是从一个子例程调用。我有点不确定在分配和解除分配之前“for_”是什么意思,尤其是在例行程序中没有进行分配的情况下。守则摘要如下: module global_variables double precision, allocatable :: input_values(:)

我正试图优化我继承的一些Fortran代码。这是一个非常重复的代码,需要几天才能运行,我正在努力减少运行时间。根据VTune放大器的说法,在减少了一些函数和子例程的运行时间后,最新的瓶颈是\u释放和\u分配,特别是从一个子例程调用。我有点不确定在分配和解除分配之前“for_”是什么意思,尤其是在例行程序中没有进行分配的情况下。守则摘要如下:

module global_variables
    double precision, allocatable :: input_values(:)
    double precision, allocatable :: input_values2(:,:)
    double precision, allocatable :: indices_array(:)
    double precision, allocatable :: value_array(:)
    double precision, allocatable :: final_result(:)
end module

subroutine func1()
    allocate( ...global values...)
    do I=1,n
        call func2(I)
    end do

end subroutine func1

subroutine func2(I)
    double precision, intent(in) :: I
    double precision :: value, x
    double precision, dimension(3) :: output_array

    call find_Indices(x)
    value_array = input_values(indices_array)
    call calculations(value)

    do j = 1,3
        value_array = input_values2(indices_array,j)
        call calculations(output_array(j))
    end do

    final_result = output_array * value

end subroutine func2

subroutine find_Indices(position)
    indices_array = some calculation on position
end subroutine find_Indices

subroutine calculations(output)
    double precision :: output
    output = some calculation on value_array
end subroutine calculations
我不得不总结而不是粘贴实际的代码,因为它的性质。分配/解除分配时间过长的子例程为func2。子例程中没有分配语句,全局值也没有重新分配。使用可用的文档,我无法确定分配/解除分配前的“for_u2;”是什么意思,也无法确定为什么在func2中花费了这么多时间。由于我指定的代码的大小,将所有数组放在堆上会导致分配,但是允许数组返回堆栈并没有减少时间

有人能帮我理解for_allocate/for_deallocate的性质吗?或者为什么这个函数要花这么多时间调用它

解决方案:

在谷歌搜索数组属性时,我遇到了另一个问题,我看到了以下帖子:

这表明修改可分配全局数组会带来很大的开销。将value_数组从可分配数组更改为指针数组(双精度,指针::value_数组(:))消除了for_allocate和for_deallocate的大部分开销,并将运行时间减少到原来的1/5。这对我来说意味着,当修改可分配数组的值时,原始数组将被释放,并分配一个新数组。这在Fortran社区中可能是众所周知的,但作为一个新用户,还没有遇到任何形式的关于这种行为的文档,这对我来说并不明显。

查看“6.间接数组访问”中的示例

重复分配(很可能)是因为在使用索引数组时,编译器分配一个临时数组(上面链接中的示例7.1)来存储生成的数组。另一种方法是显式循环索引(示例7.2)

上面的链接是针对MIC架构的,但在常规CPU上的原理可能是相同的。这里的线程还提示为数组索引创建临时数组

为了确定发生了什么,可以检查程序集输出或显式测试“显式索引”场景。

检查“6.间接数组访问”中的示例

重复分配(很可能)是因为在使用索引数组时,编译器分配一个临时数组(上面链接中的示例7.1)来存储生成的数组。另一种方法是显式循环索引(示例7.2)

上面的链接是针对MIC架构的,但在常规CPU上的原理可能是相同的。这里的线程还提示为数组索引创建临时数组


为了确定发生了什么,可以检查程序集输出或显式测试“显式索引”场景。

我们需要一些上下文。至少是一个可编译的子例程(最好是一个小程序)和您正在使用的编译器。在没有更好的信息的情况下,人们可能会猜测您需要在多个对func2的调用中保留动态数组,或者尝试堆栈与堆。输出_数组似乎最有可能被移动到堆中,分配代价高昂。for_uu仅指Fortran运行时库。我使用的是英特尔17.0编译器。我将看看如何创建一个可编译的示例。我应该意识到“for_u2;”代表Fortran,我刚刚得到的印象是Intel使用“fort”作为Fortran的缩写。请准备一个完全可编译的示例(),而不仅仅是代码摘要。好的,我下次发布问题时会记得。我们需要一些上下文。至少是一个可编译的子例程(最好是一个小程序)和您正在使用的编译器。在没有更好的信息的情况下,人们可能会猜测您需要在多个对func2的调用中保留动态数组,或者尝试堆栈与堆。输出_数组似乎最有可能被移动到堆中,分配代价高昂。for_uu仅指Fortran运行时库。我使用的是英特尔17.0编译器。我将看看如何创建一个可编译的示例。我应该意识到“for_u2;”代表Fortran,我刚刚得到的印象是Intel使用“fort”作为Fortran的缩写。请准备一个完全可编译的示例(),而不仅仅是代码摘要。好的,我下次发帖时会记得这一点。