2012-03-19 14 views
1

Fortran-OpenMPと割り当て可能な配列に関する質問があります。それは簡単です:スペースはどこに割り当てられますか?私のようなものがある場合Fortran OpenMPはどこに配置されますか

!$omp parallel default(shared) private(arr) 
!$omp critical 
    allocate(arr(BIGNUMBER)) 
!$omp end critical 

!do calculations with many arr accesses 

!$omp critical 
    deallocate(arr) 
!$omp end critical 
!$omp end parallel 

スペースはスタックまたはヒープに割り当てられますか?それは、ヒープ上にある場合は、上記のコードと最初のコードでは、この

allocate(arr(BIGNUMBER, nThread)) 
!$omp parallel default(shared) private(localArr) 
    iThread = omp_get_thread_num() 

    localArr => arr(:, iThread) 

    !do calculations with many localArr accesses 
!$omp end parallel 

deallocate(arr) 
  • のようなものとの間に差がある、2つの重要な領域が存在します。彼らは実行を遅くし、うまくスケールしないと私は仮定します。 (私は実際には、割り振りがスレッドセーブであるため、それらを残しておくことができないのかどうかは実際は分かりません)。しかし、配列がスタックに割り当てられていれば、高速アクセスのために高速になるはずです。
  • 2番目のコードでは、配列がヒープ上にあることを確認していますが、これはアクセスが遅くなります。しかし、最初のコードの配列がヒープ上にも割り当てられていれば、クリティカルな試薬を保存します+それはただ1つの割り当て/割り当て解除です。速いはずですか?
  • 配列のサイズはこれに任意のロールですか?
  • ヒープ上に割り当てられる場合は、スタックに強制的に割り当てる方法がありますか?

短い質問は基本的に問題の最適解と思われるでしょうか?

+0

'localArr => arr ...'を実行できますが、これは 'arr'がスレッド間で共有されていることを意味します。私はあなたがそれを望んでいないと思う。 'localArr'ポインタは各スレッドのコピーを持ちますが、指された内容は共有されます。あるスレッドの配列内容への変更は、他のスレッドに反映されます。 – Jason

答えて

4

OpenMPは、スタック上に自動変数(配列を含む)を割り当てる傾向があります。あなたが明示的な割り当てを行うとき、私はそれらがヒープに割り当てられると仮定しますが、Fortran標準はスタックやヒープについて全く話さないことに注意してください。例: number 1プライベート変数を割り当てているので、クリティカルセクションをそのまま残しておきます。サイズに関しては、自動配列が大きすぎるためにスタックオーバーフローが発生することがありますが、これはおそらくあなたのケースではありません。私が知らない最速のアプローチは何ですか?

編集:このプログラムは、スタック上のヒープ

integer,parameter :: BIGNUMBER = 100000000 
real,dimension(:),allocatable :: arr 

!$omp parallel default(shared) private(Arr) 
allocate(arr(BIGNUMBER)) 
    iThread = omp_get_thread_num() 

    arr = 5 

    print *, arr 

deallocate(arr) 
!$omp end parallel 


end 

と、このいずれかに配列を割り当てるように思わ

integer,parameter :: BIGNUMBER = 100000000 
real arr(BIGNUMBER) 

!$omp parallel default(shared) private(Arr) 
    iThread = omp_get_thread_num() 

    arr = 5 

    print *, arr 

!$omp end parallel 


end 
+0

よろしくお願いします。私はそれが同期しているので、クリティカルではわからなかった。クリティカルな領域が "!$ omp do"の後で、これの始まりが障壁を意味するかどうかはわかりません(do-loopを開始する前に配列を割り当てる必要があります)。だから私は私が推測する "セーブ"ルートを取っていた。しかし、割り当て時間自体は実際にはそれほど大きな問題ではないはずですが、私は批判的なものを落として何が起こるかを見てみましょう:) thx。 – Cabadath

+0

OpenMPは常にスタックに割り当てます。これを防ぐ唯一の方法は、最初の例でOPが行ったように、並列ブロック内に配列を手動で割り当てることです。 – Jason

2

OKは、ウラジミールは、ほとんどの私はだろうと言う(それが失敗しました) (標準では言及されていませんが、それは実装に完全に対応していますが、どうしてあなたの秘密を守るためにクリティカルを使用していますか?)

しかし、あなたは、スタックに割り当てられたメモリへのアクセスがヒープ上のメモリへのアクセスよりもいくらか速いと考える印象を与えます。典型的な実装では、そうではありません。アクセス時間は同じです。 スタック上のメモリの割り当ては通常、ヒープ上よりも高速ですが、割り当てられた後はアクセスする時間は同じです。だから、私はクリティカルをカットしてルート1に行きます。プライベートなものを保つのは簡単ですし、ポインタが悪いですし、メモリ割り当て時間が限られている場合は、パラレル領域を並列化するには十分な作業がほとんどありませんそれは価値がある。

+0

私は実際には、スタック上のメモリがヒープ上よりも高速にアクセスできるという前提の下にありました。今私はこれを共有/非公開と混同していますか?共有配列へのアクセスは遅くなります(ヒープ上にあることを意味すると思っていました)。privateへのアクセスは高速です(スタック)。私はここに何か逆戻りしている可能性があります。また、割り当て時間は問題ではなく、この大きな配列へのアクセスは膨大なので、できるだけ速くすることをお勧めします。 – Cabadath

関連する問題