OpenMPプログラミング

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
NGNG
オフィシャルサイト
http://www.openmp.org/

リンクなどは>>2以下で
2011/01/05(水) 00:43:11
>>304 早速のレスサンクス
そのやり方はスマートだしちゃんと規格に準拠してるね

正月最後の休みを使って公式にあるOpenMP Specifications v3.0を読んでみたんだけど
for指示文に関連付けられたforループは規格で(jp:p.44)
// for (init-expr; test-expr; incr-expr) structured-block
// structured block:C/C++では、先頭に入口が一つと末尾に出口が一つある実行文か複合文、あるいはOpenMP構文。
// 出口点は構造化ブロックからのの分岐であってはいけません。
となってるから元々breakは無理なんだな

さらにtest-exprは
// var relational-op b または b relational-op var
//var:符号付き、または符号なしの整数型の変数 or C++の場合、ランダムアクセスイテレータ型の変数 or Cの場合、ポインタ型の変数
//b:varの型と一致した型のループ不定式
となってるから
>>303の for(i = 0;i < FIN;i++){ を for(i = 0;!flag && i < FIN;i++){ にはできない
>>304ならparallelリージョンのなかのループだから&&が使えてスマートに書けるんだな

おかげさまで勉強になったよ

参考
[en]http://www.openmp.org/mp-documents/spec30.pdf
[jp]http://www.openmp.org/mp-documents/OpenMP30spec-ja.pdf
306デフォルトの名無しさん
垢版 |
2011/02/25(金) 21:14:37.06
内部関数を別の関数に渡すコード断片があると(Intel Fortranの拡張)、
例えそれが実行されなくとも、性能がガタ落ちになるようだ。理由は不明だが。
2011/04/06(水) 18:59:25.73
LinuxでもしCPUに空きがあるなら、並列数をあげるようにしたいのですが、どのようにすればいいのでしょうか?
2011/04/23(土) 16:01:03.61
linuxでノンブロッキングなconnectって
connectよんでからselectで待つのが定石だと思ってたけど
connectが成功を返すまでsleepはさんでコールし続けるってコードを見かけた
これってありなの?
2011/04/23(土) 19:20:41.40
>>308
無し
あり得ない
レスポンスが遅くなるだけ
というか誤爆?
2011/04/25(月) 18:50:56.39
>>309
すまぬ、誤爆したうえ放置してた
2011/05/19(木) 08:24:03.85
omp_set_num_threadsってOpenMPのスレッド内で呼んでも有効にならないの?
2011/05/23(月) 11:29:46.68
>>311
スレッドを幾つ起動するかを、起動してから指定するの?
2011/07/01(金) 06:24:21.77
VC++2010でシングルスレッドのループが並列化したループの有無によって
速度変わってしまうのですが、原因分かりませんか?

ttp://ideone.com/Yn67n
2011/07/01(金) 12:39:39.32
>>313
環境が判らんからなんとも言えんが、シングルスレッドのループの裏でOpenMPか何かの処理が動いているとか?
ループ前後にsleep入れて様子見てみたらどうだろう。
2011/07/01(金) 14:43:07.70
clock()はCPU時間を取得するもの
なので、裏で走るスレッドの実行時間も加算される
実時間で計測する関数を使うようにしてみればいい
316313
垢版 |
2011/07/01(金) 15:14:31.88
原因をやんわりとではありますが掴めた気がします。

ttp://ideone.com/6g1yy
上記のコードの様に、時間取得用変数にvolatileをつけると並列ループの有無に関わらず
シングルスレッドループの速度が一定となりました。

また、時間計測処理を省いて体感で測ってみましたが、
こちらでも速度が一定な感があります。
(体感の為誤差は確認出来てませんが)


この事から、時間取得とOpenMP有効時の最適化は相性が悪いのではないかと思います。
根本的な解決にはなってませんが、回避策は分かりました、有難うございました。
2011/07/01(金) 15:15:14.35
リロードしてませんでした・・・
>>315そうしてみます、有難うございます。
2011/07/17(日) 14:48:54.13
taskとsectionの使い分けって?
2011/08/11(木) 16:34:58.28
fortran90でプログラミングしてるのに、
「C/C++プログラマーのためのOpenMP並列プログラミング」を買ってしまったんだが、
大まかな部分ってCもfortranも同じなのかな?
2011/08/11(木) 19:04:57.30
その本を窓から投げ捨てて、「fortran90 OpenMP」でググって出たPDFを読んだ方が100倍マシだよ。
2011/08/11(木) 23:46:57.30
>>320
おっけ今から全力でぶん投げてくる
2011/08/22(月) 01:58:44.67
くれ。
いや、どうせなら
図書館にでも寄贈してやってくれ
2011/08/22(月) 20:50:41.53
OpenMPのスタティックなライブラリってないの?
VCだとMP使うと再頒布可能パッケージが必要だ。
2011/08/22(月) 23:49:50.97
ttp://codezine.jp/article/detail/4693

> 先ほど構成をReleaseに変えてビルドした理由は、Debugでビルドして実行するには特別なファイルが
>必要になるからです。OpenMPをデバッグ構成でビルドするには、
>「Microsoft.VC90.DebugOpenMP.manifest」ファイルと「vcomp90d.dll」ファイル(VC2008の場合)が必要になります。
>このファイルはVisual Studio 2008のStandardバージョン以上ならば
>「C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\Debug_NonRedist\x86\Microsoft.VC90.DebugOpenMP」
>にありますので、実行ファイルと同じ場所にコピーして下さい。そうすれば、
>Debug構成でも正常に実行できるようになります。

OpenMP対応を謳ってるくせに、なんでこんな面倒なことしないといけないんだろう・・・
プロパティで「OpenMP使う」ってするだけでできるようにしたらいいと思うんだけど。
(配布時は別途対応するにしても)
2011/08/23(火) 01:32:00.61
俺はフリーだろうとシェアウェアだろうと、
余計なモノをインストールさせるアプリは使わない。
2011/08/23(火) 01:56:49.13
Visual Studioなんて眼中に無さそうだね
2011/08/24(水) 20:10:32.31
>>324
その記事の筆者名でググって見たほうがよい
328324
垢版 |
2011/08/24(水) 21:41:49.47
>>327
ググってみました。
色々言われているみたいですね(汗)
もしOpenMP環境構築についての言及が誤りなら、
もっと正攻的なやり方があるということですね。
もうちと調べてみます。
2011/11/01(火) 13:47:35.24
C+11のparallel_forだとキャプチャする変数を指定する文法があることから
外側の関数からラムダ関数に変数を渡すっていうオーバーヘッドが
ありそうだけど、#pragma omp parallel forだとそのへんどうなってるの?
2011/11/15(火) 14:04:00.87
C++やC99において、OpenMPループの中で、変数を宣言するのは安全なのでしょうか?
例えば、
int sum = 0;
#pragma omp parallel for reduction(+:sum)
for (int i = 0; i < 100; i++) {
int tmp = i;
tmp++;
sum += tmp;
}

この例では、OpenMP並列化されたループ内で変数iとtmpを宣言していますが、
試してみたところ問題はなさそうです。
iもtmpもスレッドプライベート変数になると思うのですが…。
何か問題があればご教示をお願いいたします。
2011/11/15(火) 16:07:23.72
問題ないよ!
Private 扱いの理解で無問題
2011/11/15(火) 17:00:59.88
>331
ありがとうございます。これで安心して宣言できます。
今まではわざわざループの外で宣言していたので…。
2011/11/24(木) 16:58:17.76
CreateThreadで作成したスレッド内でompを使うと
スレッドが終了してもゴミスレやメモリが残ってしまうようなのですが
これを解放する関数とかありませんか?
2011/11/25(金) 08:06:46.80
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1015017355
_beginthreadex
2011/11/25(金) 12:24:01.62
_beginthreadex に置き換えてみましたがだめでした。
ompはランタイム関数ではないらしい?
2012/01/14(土) 23:38:53.03
OpenMP3.2とか出てきているみたいだけど、
OpenMPのバリア同期は関数内部でも使えるようになったのかな?
2012/04/20(金) 21:15:47.38
Android の NDK で使える様にならんかなぁ。。
338デフォルトの名無しさん
垢版 |
2012/05/03(木) 21:12:37.13
揚げ
2012/05/07(月) 19:38:56.61
質問なんですが、

do a=1,10
do b=1,50
call test1(a,b)
call test2(a,b)
call test3(a,b)
enddo
enddo

こんなプログラムを動かしたいんですけど
これをa=1,b=1の時はCPU1がtest1,2,3を動かして、
a=1,b=2の時はCPU2がtest1,2,3を動かして(ry・・・って感じに
プログラムしたいのですが、これはdoループをparallel doで挟むだけじゃダメですか?
2012/05/07(月) 19:40:00.56
>>339ですが
言語はfortranです
2012/05/08(火) 09:21:00.56
例の前に条件を言えよ
2012/05/08(火) 11:41:50.17
>>339
まあ、ふつうに
do a=1,10
を並列化して様子を見てみればいいんじゃね?
あるいは、
do i=1,10*50
a=(i-1)/50+1
b=mod(i-1,10)
,.,,,,,,,
enddo
として並列すべきループを一つにまとめて
dynamic な並列で処理するとか。
手元に本が無いので dynamic にするやり方がパッと出てこないが
2012/05/08(火) 14:55:56.02
と思ったら、b についての並列部分は
a に依存する可能性があるのか。
その場合は、2つのdo の間に
ディレクティブを入れるしかないな。

というか、まずは質問できるまで
いろいろ遊んでみるべし
2012/05/14(月) 11:39:23.47
privateって同じ変数でスレッドごとに違う数字を使えるってことだと思ってるんだけど、
これって配列をprivateに指定することってできますか?
2012/05/14(月) 15:04:04.76
できるよ
2012/05/14(月) 15:07:09.10
あ、あまり大きなサイズの配列を
private にすると、なんとか領域が
デフォを超えてエラーになるので、
何かの環境変数の値を変えないと
いけなかったハズ。
なんだっけ・・・heap だか stack だかいうヤツ。
2012/05/14(月) 17:44:28.28
>>346
stacksizeですか?ググったらそんな感じの出てきました!
ありがとうございます!
2012/05/18(金) 08:23:15.58
>>347
配列をprivateなんかにすんなよ。
ヒープに確保しておけ。
他のスレッドに触らせたくなければomp_set_lockとomp_unset_lockでアトミックしとけ。
2012/05/18(金) 08:42:39.22
通りすがりだけど、
omp_set_lock と omp_unset_lock
これの使い方がいまいちよくわかんないんだよね。
2012/05/18(金) 08:55:39.47
じゃ、使わなければいいじゃん。
判らんものを無理に使うことはないよ。
2012/05/18(金) 10:24:47.70
>>349
オブジェクトをキーにしたmonitorが分からなければそもそもマルチスレッドプログラミングが分かっていないってことだろ
2012/05/18(金) 12:14:48.44
>>349
単なるmutexじゃねーか。
353349
垢版 |
2012/05/18(金) 13:28:27.29
いじめないでくれよぅ。
shared private reduction
だけで今まで何とかなってたんだよ・・
2012/05/18(金) 14:42:29.77
OpenMPの弊害か。
やっぱりある程度基礎が必要だな。
ちなみに、omp_set_lock/omp_unset_lock
は軽くて便利だぞ。
2012/07/02(月) 18:29:55.05
これからOpenMP扱う初心者なのですがいきなり躓きました
Win7でVC++2010Expressを使用して

#include "stdafx.h"
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
printf("OpenMP Spec %d\n",_OPENMP);
return 0;
}

を実行しようとすると、ファイル 'VCOMPD.lib' を開くことができません。と表示され失敗してしまいました
ググったら構成プロパティでOpenMPサポートを「はい」にし、vcomp90.dllをPATHの通ったディレクトリにコピーするこが必要のとのこと
OpenMPサポートは解決したのですが、PATHの通ったディレクトリにコピーしてないから、vcompd.libを開け〜とエラーが起きるのでしょうか?
ちなみにVSコマンドプロンプト(2010)でpathと入力したら多くのディレクトリが表示されどこに入れればいいのか分かりません・・・
どこのディレクトリにコピーすればいいのか教えてください
2012/07/03(火) 12:43:01.12
よく分かってないなら、絶対パスで指定すればいいんじゃね
357355
垢版 |
2012/07/03(火) 12:59:16.53
>>356
上のほう読んでたら、vcomp90.dllを実行ファイルの場所にコピーと書いてあったので試してみます
それでもダメだったら、絶対パスで指定してみます。本当に初心者ですみません・・・
2012/07/03(火) 14:41:46.91
まずC++を10年勉強しろ
2012/07/03(火) 15:32:38.77
OpenMP以前にC#とか使ってみ
2012/07/03(火) 16:31:39.87
>>358
すみません、初歩的なJavaやC言語しか学んでなかったんです;;
でも菅原清文著のC/C++プログラマのためのOpenMPという本で、C言語でも扱えるということで始めてみました

>>359
はじめてのC#というサイトを見て頑張ってみます

ちなみに実行ファイルの場所(フォルダ)にコピーしてもエラーが起きてコンパイルできませんでした
2012/07/03(火) 17:19:47.13
エラーに出てるけどビルドに必要なのはVCOMPD.libであってvcomp90.dllじゃないんで
2012/07/03(火) 19:49:27.49
>>355
VS2010 (=verison 10.0) なのに、なんで vcomp90 (=version 9.0 : VS2008用) を
指定してたりするの?

あと、Debug用ライブラリ (vcompd.lib = Visual C++ OpneMP, debug) 使うなら、
VS2010 Pro (=有料版) が必要。

解決方法を4つ考えてみた:
(1) VS2010 Professional を買う
(2) VS2008 Express + Windows SDK 7.0 を使う
(3) Cygwin や MinGW をインストールして、付属のgcc/g++ を使う
(4) Linux や *BSD を使う (VMware/VirtualBoxでも併用すればよろし)
2012/07/03(火) 20:26:40.35
VC++のOpenMPはデバッグビルドだと_DEBUGをundefしてからomp.hをincludeしないといけないってのが昔あったが
2012/07/03(火) 23:09:00.31
VS2010 Pro 評価版を Virtual PC とかの捨て環境にインストールすれば vcompd.lib も入ってるけど、これコピーして使ったら逮捕されるかもしれないからやめたほうがいいね。
365355
垢版 |
2012/07/04(水) 16:57:37.98
>>361-364
多数のレス本当にありがとうございます。
とりあえずVS2010Expressでは、OpenMPが使用できないということですね
>>362さんの(2)の方法で試してみます。あと>>364さんの提案だとできそうですが・・・やめたほうがいいですね
366355
垢版 |
2012/07/24(火) 17:16:07.86
久しぶりの書き込みです
言われた通りVS2008+SDK7.0でopenmpをコンパイラ実行することができました

できればサポ3.0以上を無償ソフトで使えればよかった・・・
367デフォルトの名無しさん
垢版 |
2012/08/03(金) 08:51:06.44
メモリのローカリティって何?
2012/08/03(金) 11:28:21.30
なるべく近いアドレスのデータだけを
2012/08/27(月) 13:57:29.01
本屋にOpenMPの新しげな本が置いてあったんだけど
あれって買った方がいいと思う?
2012/08/28(火) 00:32:09.61
好きにすれば。
2012/08/28(火) 08:21:46.94
元IBMのゴルゴ13こと
青山(名前あってるかな?)先生の本がいいからなぁ。
どこかでpdf版もあったと思うけど。

初心者なら青山さんの冊子でしばらく事足りるとおもうし、
だいぶ経験積んでいるのなら、買っても言うのではないかと。
2012/08/28(火) 08:24:31.34
あと、外人さんが書いたものの日本語訳なら
いっそのとこ原書買う方がいいかも。
アマゾンか丸善に
2012/09/10(月) 09:28:48.06
ひょっとして並列できるところ全部並列化したら
かえって遅くなる?
2012/09/10(月) 10:56:02.47
そういうこともある。
2012/09/12(水) 16:33:48.58
TBBのスレってないんだね
2012/09/12(水) 16:41:28.82
http://gcc.gnu.org/onlinedocs/libstdc++/manual/parallel_mode.html

std::for_eachがOpenMP使えるみたいだけど
どんな使い方すればいいんんだろ
2012/09/12(水) 18:26:21.73
>>376
OpenMPがfor文を並列化することが多いものだから普通すぎる使い方だろ
2012/09/12(水) 23:59:00.24
イテレータの実装はスレッドセーフになってんのかね?
2012/09/20(木) 00:58:26.64
先週出た Visual Studio Express 2012 for Desktop で、
OpenMP が使えるかどうか試してみた。

WIN32 Release/Debug, x64 Release/Debug のすべてで、
omp_get_num_procs(), omp_get_num_threads() を使ったプログラムを
ビルドして実行できたよ。
2012/09/20(木) 02:12:25.71
VS 2010 ExpressはSDK入れても出来なかったのにな
2008はできていたのに

381デフォルトの名無しさん
垢版 |
2012/09/23(日) 23:36:08.84
>>373
アムダールの法則
382デフォルトの名無しさん
垢版 |
2012/10/17(水) 09:15:52.02
OpenMP有効で、Core i 3 530(2.93GHz)の環境で
23.66Gflops出た。理論値は23.44Gflopsだが・・
OpenMP簡単でスゲーな
2012/10/17(水) 17:33:00.60
結果が壊れてないか確認する必要はあるけどね
2012/10/18(木) 15:22:42.12
spec.org だっけ・・・わすれたwけど
にSMP マシンのテストで
どういうコンパイルオプションを使ったか書いてあるので
それと同じでやってみるとなおいいかも。

ものにもよるけど、経験上は20CPU(コアか・・)くらいまでなら
コア数に比例して上がっていくよね。
大規模流体計算とかだとMPI とかになるだろうけど、
それでも、OpenMP はデュアルコアが一般になった今日では簡単でとても便利だ。
2012/10/21(日) 22:56:24.36
>>384
OpenMPがいいかMPIがいいかの違いは、
共有メモリがいいか分散メモリがいいかの違いだけ。
大規模問題は往々にしてメモリ帯域が足りなくなったり、ロックの問題が出てくるから、MPIが使われる。
それ以外はOpenMPのほうが有利。

あと、メモリに依存しないオンキャッシュで収まる問題なら、
MPI、OpenMPに限らずほぼコア数にスケールする。
しかし、OpenMPで20コアまでスケールするような問題は見たことがないな。

2012/10/21(日) 23:34:46.32
Opteron 24コアだと8コアくらいまでがリニアに速くなって
それ以上は足せば速くなるけど少しの違いだったな
メモリの帯域が問題だと思ってたけど
2012/10/22(月) 00:15:04.44
>>386
Opteronで6コア以上だったらNUMAだからメモリバインドをしっかりしないとスピードは上がらんよ。
Linuxならnumactlが必要。Windowsは残念ながらOS任せなので、スケールは難しい。
2012/10/25(木) 04:31:05.92
MPIだと一部だけパージ可能だからその点は楽
389デフォルトの名無しさん
垢版 |
2013/08/05(月) NY:AN:NY.AN
openmp を使って並列化したプログラムを intel fortran コンパイラでコンパイル(最適化は -O0)して4コア(Xeon 5150)のマシンで実行したところ、-openmpオプションの有無によってかかる時間が
有:実時間3m39s、ユーザーcpu時間14m22s
無:実時間2m53s、ユーザーcpu時間2m53s
のようになりました。
つまり openmp で4コアを使っているのに実時間は減っておらず、cpu 時間がコア数の数にだいたい比例して増えています。

まったく同じプログラムを別のマシン Core i5-3470S で同じバージョンの ifort で -openmp オプション付きでコンパイル・実行したところ、かかった実時間は (-optionmp 無しでの実時間)/コア数より少し大きい程度だったので、このマシンでは問題が無さそうです。

どういった原因が考えられますか?
2013/08/06(火) NY:AN:NY.ANID:ptOJnDCf!
>>389
memory-boundなプログラムなのでは?
Nehalem前後で並列性能が大きく変わるはず。
2013/08/06(火) NY:AN:NY.AN
>>389
ロックのしかたがクソとか
プログラム依存の話なのか環境の話なのか切り分けるために
配列要素を合計するような単純なforループで試してみたらいいんじゃないのかな
CPU時間が増えているということは複数コアが使われているのは確かだと思うけど
普通はコア数に比例してCPU時間が増えてコア数に反比例して実時間が減るよね
2013/08/06(火) NY:AN:NY.AN
処理を分割せずに同じ処理をマルチコアで実行してしまっている気がする
393389
垢版 |
2013/08/07(水) NY:AN:NY.AN
みなさんありがとうございます。
FGSL のプログラムを使って多数回のモンテカルロ積分をしていて上記のような問題が起きたのですが、private, shared などの指定がまずかったようです。
積分値が異常ではなかったので、答えは間違いないが Xeon では時間短縮できていないと誤解してしまいました。しかし積分値の分散は openmp ありのほうが小さいので、どうも何らかの異常があったようです。

モンテカルロ積分に関係する量をすべて private にし、乱数の種をスレッドごとに異なる値にすることによって、積分値の異常も計算時間の異常も解決したようです。
ありがとうございました。
2013/11/23(土) 01:04:27.62
critical (name)
のnameってグローバル?
あるライブラリで
#pragma omp critical(hoge)
があった場合、別のライブラリの
#pragma omp critical(hoge)
と衝突する?
2014/05/08(木) 22:30:36.12ID:9TYJ/CaO
>>394
Cの場合、グローバル変数とローカル変数の名前が被っている時はローカル変数の方が優先されるので、衝突は起こりません
396デフォルトの名無しさん
垢版 |
2014/11/06(木) 04:20:52.83ID:iaZsweTc
何これ言語?
2014/12/01(月) 17:06:44.85ID:K0YH10ym
2015/01/21(水) 08:16:38.01ID:2itpjj+z
2015/01/21(水) 21:47:03.58ID:WAMGwClq
2016/02/05(金) 21:06:34.41ID:pgxZ4RMK
つい最近、凝縮体の数値計算でお世話になりました
といっても6時間程度の規模の計算量でしたけど
401デフォルトの名無しさん
垢版 |
2017/04/08(土) 10:41:47.71ID:8WOwQIDe
ものすごく過疎っているね
OpenMPでGPUを使う時にC++のvectorくらい使わせてくれないものか
全くの素人だから知らないだけかも知れないけど・・・
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況