並列計算について

このQ&Aのポイント
  • 並列計算の効果を最大化するための方法として、スレッド数の最適化が重要です。
  • 現在の状況では、使用するスレッド数が最適ではないため、プログラムの実行時間が倍増してしまっています。
  • この問題を解決するためには、スレッド数を適切に設定することが必要です。
回答を見る
  • ベストアンサー

並列計算について

あまりパソコンに詳しい方ではありません。 今、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スレッドは常に仕事をしていません。 原因、及び解決方法はあるでしょうか?

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

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

各スレッドで個別に使う変数をPRIVATEに指定してありますか? CRITICALとかBARRIER等の制御を使っていませんか? 並列計算は、各スレッドが独立している(他のスレッドと関係が無い)ほど効率がよくなります。 OpenMPでは、PRIVATEに指定していない変数はSHARED扱いになり、各スレッドで共有しようとするので、独立性が落ちます。 CRITICAL等の制御は必要なケースもありますが、他のスレッドを待ったりするために効率が落ちるので、最低限の利用に留める(できれば使わずに済むアルゴリズムにする)必要があります。

その他の回答 (1)

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.1

メモリアクセスが多くなるとメモリアクセスが足を引っ張りますのでマルチCPUの効果が薄れると思います。なので各スレッドは出来るだけ狭いメモリ領域を参照することが望ましいです(256KBを超えるランダムアクセスは低速化の要因)。 一番良いのは計算が複雑で変数や配列アクセスが極力少ないコードです。 あとCorei7 970だと実コア数は6で、倍の12に見えるのはハイパースレッディングの機能ですがプログラムの組み方次第ではハイパースレッディングでは効率的には動きません。場合によってはハイパースレッディングを切ってコア6で動かしたほうが早いかも知れません。

関連するQ&A

  • WindowsとLinuxのOpenMPコンパイル

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

  • Linuxマシンの複数台による並列計算環境の構築

    LinuxのPCが複数台、ルータ(ハブ)で接続されています。 これを用いて並列計算環境を構築したいと思います。サイトなどで調べたら以下のようにあっさりと書いてあります。 ○ OpenMPのインストール sudo apt-get install openmpi-bin openmpi-dev ○ 公開鍵認証を使い、パスフレーズなしで各ノードにsshでログインできるようにしておく。 その後は、実際に計算例などが出ていました。これだけで環境構築ができるらしいです。OpenMPだけでなく、MPICHによる環境の構築も出ていましたが。 そこで質問ですが、 1.OpenMPのインストールは複数台あるPCの中の1台だけでやるのでしょうか。それとも全部でやるのでしょうか。sudo ...以下のコマンドラインは各PC(ノード)でやるのでしょうか。 2.コンパイラは各PC(ノード)に個別にインストールされている必要があるでしょうか。 3.最近のGCCにはすでにOpenMPが含まれているとのことです。これは1つのPCでCPUを分割して計算する場合に用いるらしいですが、グリッドコンピューティングの場合、やはり別途OpenMPの環境設定が必要なのでしょうか。 4.gccの場合、gfortranもインストールされるようです。intel fortranで利用する場合、OpenMP(あるいはMPICH)の環境が設定できれば実行可能なのでしょうか。 5.OpenMPとMPICHによる並列環境が両方共確立しているということは無意味でしょうか。あるいは不可能なものでしょうか。使い分けができるかどうかということでもありますが。 6.話がころっと変わりますが、MACの場合、もっと簡単にできると聞いたことがあります。最近はMACにもgccが標準で入っているようで、1つのPCでの並列化はコンパイラにオプションをつけて実行できるようです。これが複数台のPCではどうなるでしょうか。 以上、よろしくお願いします。

  • 並列処理についてですが、

    並列処理についてですが、 SCOREという並列環境を構築するソフトで、4つのPC(CPU:Quad Core)を、並列化させ、 ある逐次プログラム(C言語、ラプラス方程式を差分法で解くプログラムですがプログラム内容はあまり関係ないので、あるプログラムとさせていただきます)を並列処理させたところ、 1つのPCで、4つのプロセッサを使用し、合計4ノードで並列処理を行った場合と、・・・(1) 4つのPCで各PC1台につき1つのプロセッサずつ、合計4ノードで並列処理を行った場合では、・・・(2) 同じ4ノードであるにかかわらず、 (2)がノード数に比例的に演算性能が良くなることに対して、 (1)の場合、ノード数が増えても関数log(x)(雰囲気です)をグラフにしたような形で、演算性能がうまく良くなりません このような質問を以前したところ、 ・スレッド切り替えのオーバーヘッドが影響しているのではないか ・実行環境が違うことと、ひとつのプロセスですべてのコアを占有する thread はコアを2個使えば2倍、3個使えば3倍それぞれ速くはならない。一方、PCを組み合わせて使う場合、それは完全に独立しており、データ並列のために分割されて計算量が縮小された分、PC組み合わせ数にほぼ比例して速くなる。 という回答をいただくことができました。 なんとなくで意味は分かるのですが、何卒PC初心者なもので、あまり理解することができません。 ここからが質問です。 ・「スレッド切り替え」とは一体どういったものなんでしょうか ・いただいた回答で、「ひとつのプロセスですべてのコアを占有するスレッド」とはどういうことでしょうか このことについて教えていただきたいです。スレッドとは、など部分部分での単語は調べてみましたが、 どういったように動いているのかが分かっていないせいか、上記質問のようなことが分かりません。 回答をせっかくいただいたのに自分の語彙力のせいで度重なる質問をさせていただくことを申し訳なく思いますが、みなさん回答の方よろしくおねがいします。

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

    物理計算の並列化についてお尋ねします。計算機環境(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 時間発展のループの中に、空間方向のループが何回も出てくるという構成です。計算が遅くなる理由は空間方向の格子数が極端に増えるからです。 このような場合、計算の速度を向上させるための並列化の方法についてゼロベースで教えて頂きたいのですが。ゼロベースなので、何から手を付けるべきかということですが。 よろしくお願いします。

  • 並列化プログラムのコンパイル環境と実行環境が違う

    fortran77で物理計算をしています。 パソコンが2つあって、一つは個人で使うもので、もうひとつはスパコンです。 個人PCのコンパイラはifort、スパコンはfrtが入っています。 普段は個人PCのifortでコンパイルしてからスパコンに実行ファイルを転送して走らせています。 今のところこれで問題ありません。 このプログラムを並列化して計算時間を短縮しようかなとおもっています。 mpiなりopenMPなりでプログラミングして、(もしくはifortの自動並列化コマンドを使う) (1)ifortでコンパイルしたものをスパコンに送って走らせる方法 と、 (2)スパコン内のfrtでコンパイルして走らせる方法 では 実行速度は劇的に変わるものでしょうか? frtの使い方がイマイチわからずmakeが通らないので出来れば避けたいなと思って質問させていただきました。 勉強不足な点があると思いますが、よろしくお願いします。

  • 並列計算の並列性がCPUの数が増えるほど上がる?

    並列計算をMPIを用いて行っているのですが、 CPUを2個使ったの時に掛かった計算時間を1として、 4、8、16  と使用CPU数を増やしていくと、計算速度が 1.5、10、20 と、CPU数以上に伸びていきます。 普通、CPU数以上に早くなる事は無いと思っていたのですが、1つ当たりのCPUで使用するメモリ、配列サイズが少なくなったせいで計算速度が上がることがあった、あり得る事なのかな?と思ったのですが・・・実際にCPU数よりも計算速度の速度比が上がる事はあり得るのでしょうか? 計算結果をみると、正しいです。

  • 計算機のスペックとプログラム実行速度について

    以下のような2つのPCがあります。 A Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz 2.81 GHz B Intel(R) Core(TM) i9-10900X CPU @ 3.70GHz 3.70 GHz この計算機に全く同じソースコードで同じコンパイラで実行させてみました。両者とも高速化に関する工夫を全くしない状態です。 言語はFortranで、コンパイラはgfortranです。時間発展計算で、計算の実行時間は1時間ぐらいでしょうか。 私はコンパイラの性能の分だけの違いが出るはずだと思っていましたのでBの方が3割ぐらい早いかなと思っていたのですが。実行の様子をみるとほぼ互角でひょっとするとAが勝っているような感じです。 計算の進行に従って画面にプリント表示する時間ステップの進行速度での印象です。 高性能のCPUの力を出し切るような環境になっていないとその性能は引き出せないし、逆の結果にさえなるということでしょうか。 CPUの性能をフルに引き出すにはソースコードの工夫、高機能コンパイラ、最適なコンパイラオプションの選択ということになるのでしょうか。Aの方も同様に工夫しても高速化が改善されずBがどんどん早くなる、ということなのでしょうか。

  • OpenMPによる並列処理で質問があります。

    c言語でポアソン方程式を差分法で解くプログラムを作成し、それをOpenMPで並列化して、スレッド数を1,2,4,8と増やしながら処理時間の計測をしました。  スレッド数が2の時は処理時間が短くなったのですが、4,8と増やしていくごとに処理時間が逆に増えてしまいました。デュアルコア4プロセッサなのでコア数以上のスレッド数ではないはずなのですがこれはなぜなんでしょうか? 計測した解析領域は 48×48 72×72 の二つです。どちらも4、8スレッドの時は遅くなってしまいました。以下に並列化部分のソースを載せます。並列化した場所は、連立方程式を解く部分で、求解には、ガウス・ジョルダン法を用いています。並列化でまずいところがあればそちらも指摘お願いします。 for(k=0;k<=size-1;k++) { pivot=a[k][k]; #pragma omp parallel for for(j=0;j<=size-1;j++) { a[k][j]=a[k][j]/pivot; } b[k]=b[k]/pivot; #pragma omp parallel for private(j,tmp) for(i=0;i<=size-1;i++) { tmp=a[i][k]; if(i!=k) { for(j=0;j<=size-1;j++) { a[i][j]=a[i][j]-(tmp*a[k][j]); } b[i]=b[i]-(tmp*b[k]); } } }

  • Intel+WindowsPCの並列化処理

    いまどきのPCですが、Core-i5, メモリ4G, 64ビットにintel Visual Fortran11.1.048をインストールし、コマンドプロンプトにコマンドを入力しながら利用しています。 このような状況でもCPUの分割による並列計算ができると思っています。 自分のプログラム(流体計算系)を以下のようにしてコンパイル、実行してみました。 ifort /Qparallel abc.f↓ abc.exe <ret>↓ 一応、トコトコと最後まで走っていきますが、コンパイラオプション /Qparallelをつけずにコンパイルした場合と速度はほぼ変わりません(同じと言ってもいいぐらい)。自分が何か間違っているか、並列処理では効率が上がりにくいつくりになっているのかわかりませんが。ただ、このコンパイラオプションは自動並列化で、ソースの作り方が少々悪くても対応するのではないかと思っています。 (悪いのは悪いのなりに、比率の比較はできるだろうと思うのですが) また、コンパイラオプションですが、いろんなサイトを見ると、-parallel となっている場合が多いですが、ifort -helpでオプションを調べると、/Qparallel と表示されます、これでいいでしょうか。 もう1つお願いなのですが、フォートランのプログラムで並列化オプションの有無ではっきりパフォーマンスの違いがわかる簡単なサンプルコードがないでしょうか。ラプラス方程式とかポアソンソルバーとか割とソース事態は短くて、並列効果が顕著なコードですが。ネットで見るとあることはありますが、C言語だったりします。 自分で作ると、あまり効果がわからないので、これぞ、並列効果というのがわかるとありがたいです。 また、それによって、自分の環境ががんばり次第で並列化で高速化できるという自信にもなります。 (今効果が出ないのは、ひょっとしたら並列環境のインストールにミスがあるのではないか、私が何か勘違いしているのではないかと疑いもあるからです。) 並列化の処理速度以外でこのコンパイラの動作に異常はないようです。 以上、よろしくお願いします。

  • 並列処理プログラム

    並列処理について。 画像imageの値が0より大きい場合に、managerを実行しますが、managerの計算時間が長いです。 そこで、4つのコアでpthreadにより、並列処理をさせたいんですが、 どのようにプログラムを書けばいいかすみませんが教えてください。 あるボクセルを計算中に、次のボクセルを計算するようなプログラム。。。 for (int z=0; z<32; z++){  for (int y=0; y<32; y++){   for (int x=0; x<32; x++){    if(image(x,y,z) > 0){     total += manager(x,y,z);    }   }  } }

専門家に質問してみよう