2017-06-10 10 views
1

私が継承したいくつかのFortranコードを最適化しようとしています。これは実行に数日かかる非常に反復的なコードであり、私は実行時間を短縮するために努力しています。 VTune Amplifierによると、いくつかの関数とサブルーチンの実行時間を短縮した後、最新のボトルネックはfor_deallocationとfor_allocationです(特に1つのサブルーチンから呼び出されます)。私は、 'for_'が割り振りと割り振り解除の前に何を意味するのか、特に割り振られていないので、少し不明です。次のようにコードの概要は次のとおりです。Fortranはなぜfor_allocateまたはfor_deallocateに多くの時間を費やしますか?

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_'が何を意味するのか、func2でそれに多くの時間が費やされたのかを確かめることができませんでした。ヒープ上にすべての配列を配置することを指定したコードのサイズのため、配列をスタックに戻すことはできません。

for_allocate/for_deallocateの性質を理解できる人はいますか?あるいは、この機能がそれほど時間を費やす理由は?

SOLUTION:

アレイのプロパティをグーグルでいる間、私が持っていた別の問題のために、私はこの記事に出くわした: Fortran: dynamic arrays vs. automatic array Avoiding Memory Allocation

割付けグローバル配列を変更すると大きなオーバーヘッドがあることを示しています。 value_arrayを割り当て可能な配列からポインタ配列(double precicion、pointer :: value_array(:))に変更すると、for_allocateとfor_deallocateからオーバーヘッドの大部分が削除され、ランタイムがその1/5に短縮されました。これは、割り当て可能な配列の値が変更されると、元の配列の割り当てが解除され、新しい配列が割り当てられることを示しています。これはFortranのコミュニティではよく知られているかもしれませんが、新しいユーザーとしては、この動作に関するドキュメントの形式には触れていませんが、それは私には分かりませんでした。

+0

いくつかのコンテキストが必要です。コンパイル可能なサブルーチン、少なくとも(より良いプログラムになります)、コンパイラを使用しています。 – Jack

+1

より良い情報がない場合、func2への複数回の呼び出しで動的配列を保持し、スタックとヒープを試してみることが必要な場合があります。 output_arrayはコストのかかる割り当てでヒープに移動する可能性が最も高いようです。 for_は単にFortranランタイム・ライブラリーを指します。 – tim18

+0

私はintel 17.0コンパイラを使用しています。私は、コンパイル可能な例の作成について私ができることを見ていきます。 私は、 'for_'がFortranの略であることに気がつきました。私は、IntelがFortranの略語として 'fort'を使用したという印象を受けました。 –

答えて

0

アウトhttps://software.intel.com/en-us/articles/fortran-array-data-and-arguments-and-vectorization

の「6.間接配列アクセス」の例繰り返し割り当て(非常におそらく)であるインデックス配列を使用する場合、コンパイラは、(上記のリンク例7.1)一時配列を割り当てるため結果の配列を格納します。代わりに、インデックスを明示的にループする(例7.2)。

上記のリンクはMICアーキテクチャ用ですが、原則は通常のCPUと同じである可能性があります。ここのスレッドhttps://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/685221は、配列インデックスのための一時的な配列の作成を示唆しています。

何が起こっているのかを確かめるには、アセンブリの出力を検査したり、明示的なインデックス作成のシナリオを明示的にテストする可能性があります。

関連する問題