• ベストアンサー

openMPについて

gfortranでopneMPによる並列化を行いましたが、計算速度が低下してしまいました。 OS:linux OPENSUSE corei7です。並列化は use omp_lib をいれておいて、doループの前後に !$omp parallel !$omp do DOループ !$omp end do !$omp end parallel というふうにしただけです。 CPUの使用量は10%ぐらいから一気に90%ぐらいまで上がるのですが、 計算速度は倍以上になります。 原因は何でしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

あと、共有変数とスレッド毎の変数についての記述が無いですが、ちゃんと入ってますか?

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

OpenMPはCで少し検討した程度です。 一般的に、並列処理は、それぞれが独立していると効率がよくなり、排他制御等を行うと遅くなります。 DOの中身がどうなっているか、記述が無いので断言はできませんが、その独立性がわるくて分割に向いてなかったり、ファイルや画面に出力してたり、それが混じらないように制御構文入れたりしてしませんか?

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • WindowsとLinuxのOpenMPコンパイル

    fortranを用いたプログラムをOpenMPを用いて並列化した際のトラブルについてです。 Fortranを使ってプログラムを作成しています。 Windows上でフリーコンパイラGFortranを用いて,OpenMPで記述したCPU並列化プログラムをコンパイルし,実行したところ問題なく並列計算が動作しました。 しかし,プログラム中で用いる配列や変数が多いため,Windowsでのメモリ使用制限2GBを超えてしまい,Linuxでの開発を余儀なくされました。 そのため,初心者ながらUbuntuを導入し,GFortranをインストールして同じく並列化を指示しコンパイルしたところ,2GBの制限を超えないようにしたWindowsと全く同じプログラムでも数値がおかしくなってしまいました。 Ubuntuでも,並列化の指示をせずに逐次計算を行えばWindows上と同じようにプログラムを回すことができ,正しい値が算出されています。 つまり,UbuntuではWindowsと全く同じプログラムでも並列化がうまくできていません。 なぜこのようなことが起きるのでしょうか,対処法があればお願いします。

  • 並列化プログラムの作成方法について

    物理計算の並列化についてお尋ねします。計算機環境(GPU, メモリ分散(ハブ)、メモリ共有(CPU内での並列))、コンパイラの選択とかいろいろ条件があると思います。また、作りこみの度合い(本気度)によっても違うと思います。特に並列計算は並列化の度合いによって速度が急激に伸びるなどいろいろ特性があると思います。 現時点では、 通常のパソコン(Core-i7)で、コンパイラはintel fortran, OSはWindows10というごく普通の環境です。Cygwinのgfortran, Visual studioなどもあります。 物理プログラムは、構成として以下のようです。 2次元空間の時間発展の計算です。 do n=1,nt do i=1,nx ! x方向格子へのループ do j=1,ny ! y要綱格子へのループ enddo ! x方向格子ループの端 enddo ! y方向格子ループの橋 enddo ! 時間方向ループの終端 stop end 時間発展のループの中に、空間方向のループが何回も出てくるという構成です。計算が遅くなる理由は空間方向の格子数が極端に増えるからです。 このような場合、計算の速度を向上させるための並列化の方法についてゼロベースで教えて頂きたいのですが。ゼロベースなので、何から手を付けるべきかということですが。 よろしくお願いします。

  • OpenMPのリダクション演算を自分でする方法

    OpenMPでプログラムを並列化しているのですが、以下の内積を並列化する際にreduction演算をしなくてはなりません for( i=0; i<N; i++ ){  r += x[i] * y[i]; } ↓ #pragma omp for reduction(+:r) for( i=0; i<N; i++ ){  r += x[i] * y[i]; } このように、for文に対してreduction節を入れてスレッド並列化するのが普通ですが、ここでBLASというライブラリを使いたいので、reductionを自分でしたいと考えています int INC = 1; int n = i_end - i_start; for( i=i_start; i<i_end; i++ ){  r += ddot_( &n, &(x[i_start]), &INC, &(y[i_start]), &INC ); } /* reduction here */ 0~N-1までの配列の要素を、自分でスレッドに分けて、i_start~i_endまでの要素の内積を各スレッドがddot_関数を使って計算します その後、reductionの計算をする必要があるのですが、一体どうすればreduction演算ができるのか分かりません どなたか分かる方、ご教授ください なお、スレッド並列版のBLASは使わない予定です あくまで、自分でスレッド並列化を行ない、その中で逐次版BLASを呼び出すという方向で考えています

  • 計算速度

    a(m,n) m=20000 n=10000 のとき do j=1,n do i=1,m x=x+a(i,j) end do end do の計算速度と do j=1,n do i=1,m x=x+a(j,i) end do end do の計算速度が違うのはなぜですか?

  • fortran

    do I = 1,40 do F = 1,4 do L = 1,100 if (I == 1. .OR. L == 1.) then A (I,F,L) = 3. else A (I,F,L) = 3.* B (I-1,F,L) end if end do end do do F = 1,4 do L = 1,100 do M = 1,100 B (I,F,L) = B (I,F,L) + C (I,F,M,L) end do end do end do end do 簡素化したプログラムなので、わかりにくいと思うのですが、後で計算するB(I,F,L)をA(I,F,L)のDOループに最初に持ってくると、I=1orL=1のときは正しい計算をしてくれるのですが、そのほかのときはB(I-1,F,L)に値が入らないのです。ちなみにC(I,F,M,L)はA(I,F,L)のループの後に計算しましたが、省略しました。 ご回答よろしくお願いします。

  • Can't locate R.pm in @INC

    perl初心者でまた質問させていただきます。 CGIを作っているのですが、R.PMが使えなくて困っています。 USE R; とすると、以下のようなエラーが出てしまいます。 Can't locate R.pm in @INC (@INC contains: /usr/lib/perl5/5.10.0/x86_64-linux-thread-multi /usr/lib/perl5/5.10.0 /usr/lib/perl5/site_perl/5.10.0/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.10.0 /usr/lib/perl5/vendor_perl/5.10.0/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.10.0 /usr/lib/perl5/vendor_perl .) at /srv/www/htdocs/cgi/ringo.cgi line 5. BEGIN failed--compilation aborted at /srv/www/htdocs/cgi/ringo.cgi line 5. Premature end of script headers: ringo.cgi そこで、 locate R.pm で、場所を探しました。 /usr/lib/perl5/5.10.0/x86_64-linux-thread-multi/R.pm ということで、 use R '/usr/lib/perl5/5.10.0/x86_64-linux-thread-multi/'; このように変えてみたものの、同じエラーです。ちなみに、CGIではなく、PERLのプログラムからだと、use R;で動作することは確認しました。 よろしくお願いします。

    • 締切済み
    • CGI
  • FORTRAN subroutineと配列と繰り返し

     以下のように二次元配列の場合でsubroutineを使うときに、主プログラムで2重Doループ(iとj)で繰り返しをしているのですが、すでにsubroutineでDoループ(i)を用いて計算しています。これではsubroutineの利点をうまく使えていないと思うのですが、subroutineを使って配列、Doループをきれいにする方法をどなたか教えていただけませんか。  実際は4重ループ、4次元配列なので、プログラムをわかりやすくするためにサブルーチンを使いたいと思っています。 -------------------------------------------------------------- program S real,dimension(5,5) :: B real,dimension(5) :: A integer :: i,j do j=1,5 CALL sub1(A) do i=1,3 B(i,j)=A(i)*j write(*,*) B(i,j) end do end do end program S subroutine sub1(A) real,dimension(5) :: A integer :: i do i=1,3 A(i)=3.*i end do end subroutine sub1

  • PC(並列化)の処理能力について

    現在、linux環境下で並列計算機を用いて、電子状態計算等の並列処理を行っています。 処理速度、処理能力についてですが、 計算ホストを1台から2台に増やすと、倍の処理能力を持つようになりました。 しかし2から3、3から4台にしていくと、今度は比例的にではなく、 ある処理速度に収束するような結果となりました。 これは、何が原因と考えられるのでしょうか? もしくは計算規模が小さいために、このような結果となるのでしょうか? 例えば、計算する空間を増大すると比例的に処理能力が 向上するのでしょうか? ご面倒かと思いますが、回答お願いします。

  • rubyでパケットキャプチャ出来るプログラムを実行したところ、以下のよ

    rubyでパケットキャプチャ出来るプログラムを実行したところ、以下のようなエラーメッセージが出力されました。 上位4つのwaraningとno suitable device foundのエラーを回避する策を教えて頂きたいです。 $ ruby packet.rb /usr/local/lib/site_ruby/1.8/i486-linux/pcap.so: warning: do not use Fixnums as Symbols /usr/local/lib/site_ruby/1.8/i486-linux/pcap.so: warning: do not use Fixnums as Symbols /usr/local/lib/site_ruby/1.8/i486-linux/pcap.so: warning: do not use Fixnums as Symbols /usr/local/lib/site_ruby/1.8/pcaplet.rb:41:in `lookupdev': no suitable device found (Pcap::PcapError) from /usr/local/lib/site_ruby/1.8/pcaplet.rb:41:in `initialize' from packet.rb:12:in `new' from packet.rb:12 プログラムは、以下のサイトにあるものを利用しています。 http://d.hatena.ne.jp/tullio/20080217/1203261760 #!/usr/local/bin/ruby require 'pcaplet' include Pcap class Time # tcpdump style format def to_s sprintf "%0.2d:%0.2d:%0.2d.%0.6d", hour, min, sec, tv_usec end end pcaplet = Pcaplet.new pcaplet.each_packet { |pkt| print "#{pkt.time} #{pkt}" if pkt.tcp? print " (#{pkt.tcp_data_len})" print " ack #{pkt.tcp_ack}" if pkt.tcp_ack? print " win #{pkt.tcp_win}" end if pkt.ip? print " (DF)" if pkt.ip_df? end print "\n" } pcaplet.close 以上、宜しくお願い致します。

  • 並列計算について

    あまりパソコンに詳しい方ではありません。 今、linuxが入ったパソコン(CPU:Intel(R)Core(TM)i7 CPU970@3.20GHz,コア数12, メモリ:5.8GiB)で数値計算をしています。コンパイラはgfortranです。OpenMPを使って、並列計算をしています。 例えば、スレッドを5使って一つのプログラムの計算したとします。次に別のプログラムをスレッドを5使って同時に計算したとします。 CPUモニタで確認すると、合計12スレッド中、10スレッドが使用率100%になります。 しかし、計算時間はそれぞれ倍ぐらいになってしまいます。結局、プログラムを1 つずつ計算するのと同じ時間がかかります。また、使用するスレッドは5ぐらいが最適であることがわかっています。(それ以上多くしても計算時間が多くなるだけ)。つまり、12スレッド中7スレッドは常に仕事をしていません。 原因、及び解決方法はあるでしょうか?