マルチスレッドプログラミング相談室 その8

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
マルチスレッドプログラミングについて語るスレ

■前スレ
マルチスレッドプログラミング相談室 その7
http://pc12.2ch.net/test/read.cgi/tech/1215253576/

■過去スレ
その1 ttp://pc3.2ch.net/tech/kako/997/997345868.html
その2 ttp://pc5.2ch.net/test/read.cgi/tech/1037636153/
その3 ttp://pc8.2ch.net/test/read.cgi/tech/1098268137/
その4 ttp://pc8.2ch.net/test/read.cgi/tech/1130984585/
その5 ttp://pc11.2ch.net/test/read.cgi/tech/1157814833/
その6 ttp://pc11.2ch.net/test/read.cgi/tech/1187008532/

OS・言語・環境は問わないが、それゆえ明記すべし。
テンプレ
【OS】
【言語】
【実行環境】
【その他特記する事項】
2デフォルトの名無しさん:2009/09/21(月) 17:19:50
■関連スレ・関連性の高いスレ

【マルチコア】並列化について語る【使いこなせ】
ttp://pc11.2ch.net/test/read.cgi/tech/1137540671/

pthread地獄 part 2
ttp://pc11.2ch.net/test/read.cgi/unix/1166620307/

ネットワークプログラミング相談室 Port24
ttp://pc12.2ch.net/test/read.cgi/tech/1246895188/
3デフォルトの名無しさん:2009/09/21(月) 20:58:08
>>993
> lock-freeをある程度かじれば分かるが、要素数もatomicじゃなくていいよ
> スレッド状態は特権リング内の管理だろうから内部の挙動はシラネ
> ユーザーレベルで言うなら、lock-free queueをスピン&スリープで待機するなら
> スレッド状態も持つ必要なし

spinlock なら普通はスリープじゃなくて再スケジュー
ルじゃないだろか。まぁいいけどさ。

でか、spinlock 使う位なら俺にとってはキュー操作と
一緒にやる作業の大きさで mutex にするか spinlock
にするかってだけの話になって、キュー自体にはやっぱ
り排他責務なんか持たせないなぁ…。

あ、「キューに特化するとキューの特性に沿ったとても
効率の良い spinlock 的な何かがある」ってこと?

それとも、生産者が一つ生産してキューに生産物を入れ
る度に上限数まで消費者スレッドを起こして、とかいう
生産時間<<消費時間な場合に使うわけ? 確かにこの場合
は有効そうだけど。
4デフォルトの名無しさん:2009/09/21(月) 21:37:19
スレ立て乙
5デフォルトの名無しさん:2009/09/21(月) 23:32:10
mutexとspinlockの使い分けが全く要らないと思ってるなら、単に畑違いだと思うよ…
6デフォルトの名無しさん:2009/09/21(月) 23:34:52
>>3
普通にlock-free queueを全く分かってなくね?
アトミック操作も要らないタイプすら作れるんだが、何でキュー自体に排他機能とか
変な話になってるんだ。
7デフォルトの名無しさん:2009/09/21(月) 23:43:16
>>6
>アトミック操作も要らないタイプすら作れるんだが
詳しく
8デフォルトの名無しさん:2009/09/21(月) 23:47:28
ぶっちゃけ、新スレまで引っ張るなよと言いたい。
低水準の要る要らないなんて、まともに終わったためしが無い。
9デフォルトの名無しさん:2009/09/21(月) 23:48:36
>>7
lock-free queueはメモリバリアだけで十分作れるよ。前提条件によるけど。
10デフォルトの名無しさん:2009/09/21(月) 23:53:04
CAS無しでやる話とかは前スレで出てたな
11デフォルトの名無しさん:2009/09/21(月) 23:53:42
>>9
大変失礼、そう言うことですね。
勘違いしておりました。
12デフォルトの名無しさん:2009/09/21(月) 23:58:07
lock-free queueでスピンってspin-waitであってspin-lockじゃなくね
そもそも"lock-free"の意味的にlockする訳が
13デフォルトの名無しさん:2009/09/22(火) 00:08:35
lock-free queueって、計算処理は非常に重いけど、スレッドモデルとしては
比較的単純なケース(マスタ-スレーブモデル)に利用されるものなのかな?

たとえば動画エンコ/3Dレンダ/科学計算といった応用のように、
親スレッドが複数の子スレッドを生成し、各子スレッドが計算処理を実行し、
結果をlock-free queueに追加していく。親スレッドはjoinですべての計算の
終了を待ち、joinから抜けたらqueueから順に計算結果を取り出す...みたいな。
このモデルだと、スレッド間の同期なんて考える必要はまったく無い。

>>3の生産者-消費者モデルというのは、スレッド間同期の代表的な題材だから、
lock-free queueの話題とするのは、そもそも畑違いであると。

lock-free queueについては分かっていないので、有識者の指摘たのむ。
1413:2009/09/22(火) 01:44:44
(>>13の続き)

あるいは、>>13の応用ならリアルタイム性は要求されず、しかも
計算処理が(親スレッドの処理よりも相対的に)重いという前提があるから、
親スレッドは全子スレッド群の終了を(joinで)待ってから再開しなくても、
pollingで定期的にqueueから計算結果を取り出し、ゆっくりと
計算処理の進捗状況に合わせて出力(画面表示)していく方法だってある。
これもスレッド間の同期は考えなくてもいい。

なにかlock-free queueの利用イメージが見えたような気がするのは漏れだけ?
lock-free queue専門家からすれば「何を今更、そんなの常識」な話なのかな?
15デフォルトの名無しさん:2009/09/22(火) 02:22:42
そういう使い方はたぶん一般的だろうと思う
一対一の一方通行queueを双方向に張って適当にポーリングして同期っぽいことも
やれるし

ただ、汎用性をちょっと変えただけで実装が変わるから、結局バスロックするような
queueもあるだろうし、その辺ひっくるめてまとめて語るほどの経験は無いし
16デフォルトの名無しさん:2009/09/22(火) 08:54:48
>>6
> 普通にlock-free queueを全く分かってなくね?
> アトミック操作も要らないタイプすら作れる

lock-free と wait-free を混同してね?
17デフォルトの名無しさん:2009/09/22(火) 09:13:03
wait-freeが作れるならlock-freeでもあるからいいんじゃね?
18デフォルトの名無しさん:2009/09/22(火) 09:43:04
>>6
是非作り方を教えてくれ。
アトミック操作もいらないなんて、君にとっては些細なことでも俺にとっては非常に大きな一歩なんだ。
19デフォルトの名無しさん:2009/09/22(火) 17:21:21
どう見ても「本当は知らないんだろ?」と煽ってるようにしか見えないが…

ちょっと真面目に考えてみろよ。書き手が単数の場合、アトミック操作は要るか?
メモリバリアだけで書けるだろ。wait-freeじゃなくてlock-freeなんだから、準備
できてない間は待ってて貰っていいんだぞ。
複数の書き手を作るには、ハブのようなスレッドを作ってスター型トポロジーに
すればいい。

つーか、コードを全部示さないと信用できないってんなら、信用されなくていい。
勝手に妄想家とでも思っててくれ。いちいち何から何まで言うつもりは無い。
20デフォルトの名無しさん:2009/09/22(火) 17:37:30
顔真っ赤にすんなよ^^;
21デフォルトの名無しさん:2009/09/22(火) 17:48:31
妄想乙
22デフォルトの名無しさん:2009/09/22(火) 20:44:22
>>19
> ちょっと真面目に考えてみろよ。書き手が単数の場合、アトミック操作は要るか?
ん、「書き手が単数」ってのはどこからわいてきた話だ?
こういうのは設計・実装に大きく影響する話なんだから、
勝手に仮定されると議論が成り立たないと思うぞ。

というか、読み手と書き手がそれぞれ一つずつって前提が置けるのであれば、
CASなしでwait-freeなキューを作るのは難しくないし。
2313:2009/09/22(火) 20:46:03
>>14

レスありがとうございます。まずは、マスタ-スレーブモデルは一般的だろうと
いうことで、lock-free queue勉強の一歩を進めることができます。

あと、>>14のポーリング方式はスレッドプールモデルにも適用できますね。
スレッドプールとポーリングの組み合わせたキーワードで考えると、
更にlock-free queueの応用範囲が広がる気がします。
24デフォルトの名無しさん:2009/09/22(火) 21:02:24
>>22
書き手が複数の場合どうするかも書いてあるだろ…
25デフォルトの名無しさん:2009/09/22(火) 21:11:17
>>24
「ハブのようなスレッドを作ってスター型トポロジー」みたいな構造は
もはや「書き手複数で使えるキュー」とは言えないと俺は思うがねえ…
「ハブのようなスレッド」がそれぞれの書き手と繋がったキューを
順次ぐるぐるとチェックして回るんだろ?
それだけでCPUの1コアの使用率が100%になっちまうじゃねえか。

で、読み手が複数の場合はどのように対処するんで?
26デフォルトの名無しさん:2009/09/22(火) 21:24:00
>>25
横だけど「ハブのようなスレッド」が渡して回るんじゃないの?
ほとんど(まったく?)lock-freeの利点が活きていないけど。
27デフォルトの名無しさん:2009/09/22(火) 21:25:03
前スレからの元々の流れ忘れてる奴多くね?
俺も忘れたけど
28デフォルトの名無しさん:2009/09/22(火) 21:36:59
まとめると、
書き手がひとつならアトミック不要、複数ならアトミック必要ですね。
読み手も同様
29デフォルトの名無しさん:2009/09/22(火) 21:43:39
>>27
そんな君たちに僕の質問を再度コピペしておこう
| メモリとかキャッシュとかレジスターとかバスとかマルチコア/プロセッサーが絡むと
| どうなっているのかよくわからないからいつもmutex頼みです
| これらのHW関連とマルチスレッドについて詳しく知りたい場合のよい方法を教えてください
30デフォルトの名無しさん:2009/09/22(火) 21:52:54
アセンブラでアトミック命令使ってみることをお勧めするであります。
31デフォルトの名無しさん:2009/09/22(火) 21:55:29
>>26
> 横だけど「ハブのようなスレッド」が渡して回るんじゃないの?
キューだよ? FIFOだよ?
2つの読み手R1とR2がいて、R1はガリガリ計算中、
R2がキューから次の要素が来るのを待っているって状態なら、
次の要素はR2に渡さないといけないんだよ?
32デフォルトの名無しさん:2009/09/22(火) 21:59:00
もしかして、lock-free, wait-freeの "wait" を
sleep()とかyield()とかのことだと勘違いしている奴がいるんじゃないか?
33デフォルトの名無しさん:2009/09/22(火) 22:24:00
と、このような有様ですので、lock-freeのライブラリなんかそうそう出回らないって訳です
34デフォルトの名無しさん:2009/09/22(火) 22:43:58
www
俺以外全員馬鹿wwwww
wwwwwwwwwwwwwwwww
35デフォルトの名無しさん:2009/09/22(火) 23:35:51
>>32
lock-free queueとは、スレッド間で共有するキューがあっても、
そのアクセスに「lock操作そのものが不要(free)」なキューである。

これは分かる。

では、wait-free queueとは、スレッド間で共有するキューがあり、
たとえそのキューが空であっても「wait操作そのものが不要(free)」な
キューである。

うーみゅ、どうやって実装しているんだ?それとも何か勘違いしてる?
分かんねーーーヨ....orz
36デフォルトの名無しさん:2009/09/23(水) 00:18:28
lock-freeはロック(mutexとか)がかからないけどCASなど無限時間の可能性がある。
wait-freeはロックがかからないし、一定時間で完了する。
でいいのかな?
37デフォルトの名無しさん:2009/09/23(水) 00:30:03
>>36
いいんじゃないかな
38デフォルトの名無しさん:2009/09/23(水) 00:31:06
>>36
> lock-freeはロック(mutexとか)がかからないけどCASなど無限時間の可能性がある。
CASで失敗したときは操作を繰り返す、ってのは lock-free なの?
だとしたら、スピンロックは lock-free ってことになるよね?
39デフォルトの名無しさん:2009/09/23(水) 00:33:51
>>38
ロック変数をspinlockするのなら、それはlock-freeとは言えない
40デフォルトの名無しさん:2009/09/23(水) 00:45:03
>>35
キューが空ならnullを返したり例外を投げたりすればいい。

たとえばJavaでは、要素が空のときにnullを返したりする Queue と、
要素が空のときに新たな要素が来るまで待機する操作がある BlockingQueue とが、
ちゃんと区別されている。
で、Queueにはwait-freeな実装クラス ConcurrentLinkedQueue があるけど、
BlockingQueueの実装クラスである LinkedBlockingQueue や ArrayBlockingQueue とかは
wait-freeでもlock-freeでもない。

で、君が欲しいのは Queue なの? BlockingQueueなの?
41デフォルトの名無しさん:2009/09/23(水) 00:47:32
>>39
ロック変数をCASで変更しようとして失敗したらリトライってのはlock-freeではない。
リンクリストのポインタ変数とかをCASで変更しようとして失敗したらリトライってのはlock-freeである。
ってこと?
42デフォルトの名無しさん:2009/09/23(水) 00:53:59
>>41
うん
4335:2009/09/23(水) 06:49:21
>>40
レスありがトン。詳しい解説は、とても助かる。

欲しいのは、待機が可能なwait-free queueの実装クラスです。

この場合には、ConcurrentLinkedQueueでキューを生成し、
nullあるいは例外発生であればスレッドを(たとえばwait操作で)待機させるよう
アプリケーション側で実装することになるのでしょうか?
スレッドを待機させる方法はwait操作以外にもいろいろあるから、
どの方法を選ぶかはアプリケーションにまかせる、という考え方になります。

wait-free queueの意味が「wait操作そのものが不要なキュー」(>>35)ではなく、
「wait操作を実装していないキュー」の意味に思えてきました。

こんな感じで合っていますか?
44デフォルトの名無しさん:2009/09/23(水) 09:15:31
LinkedListを使ってキューを作るならCASを使うのでlock-freeだがwait-freeにならない。

もし読み手をwaitでブロックさせるなら文字通りlock-freeでもwait-freeにもならない。
その場合、書き手はブロックした読み手を起こすためにカーネルの世話になるのでlockが発生するかもしれない。
45デフォルトの名無しさん:2009/09/23(水) 11:23:13
>>43
> 欲しいのは、待機が可能なwait-free queueの実装クラスです。

「待機が可能な」ってことは BlockingQueue が欲しいってことだね。

BlockingQueueの実装方法は2つ。
・待機しないQueueを用意し、要素が空だったらスピンしまくる。
・「キューが空でない」という条件変数を用いたモニタ同期を組み込む。
前者は明らかにCPUの無駄遣い。
後者はlock-freeでもwait-freeでもない。

てことで、>40にも書いたようにJavaのBlockingQueueの実装クラスが
wait-freeでもlock-freeでもないのは、手抜きしているわけではなく
そのように実装するのが不可能だからだ。

> wait-free queueの意味が「wait操作そのものが不要なキュー」(>>35)ではなく、
> 「wait操作を実装していないキュー」の意味に思えてきました。

だからそれは "wait-free" って言葉の意味を誤解してるって。
"wait-free" の wait とは、モニタ同期のwait()操作とかとは別物。
もちろん、sleep()とかyield()でもない。
46デフォルトの名無しさん:2009/09/23(水) 11:27:50
>>44
> LinkedListを使ってキューを作るならCASを使うのでlock-freeだがwait-freeにならない。

CASを使った wait-free なQueueの実装はあるよ。
http://java.sun.com/javase/6/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html
47デフォルトの名無しさん:2009/09/23(水) 11:41:43
連結リスト使うくらいなら別にmutexでも、と思いかけたが、mutexは格段に重いから
そうも言えないか
48デフォルトの名無しさん:2009/09/23(水) 11:47:45
>>47
> mutexは格段に重いから
Win32のmutexが無駄に重いだけ。

最近のOSが用意しているmutexなら、競合がない場合のコストは
ロックとアンロックそれぞれで高々CAS一回分程度。
49デフォルトの名無しさん:2009/09/23(水) 11:50:23
なら連結リストよりmutexの方がいい場面は多そうだな、Windows以外は
50デフォルトの名無しさん:2009/09/23(水) 11:50:28
Win32のmutexはプロセスレベルじゃなくてシステムレベル?
で排他してるから重いのはしょうがないかと・・
51デフォルトの名無しさん:2009/09/23(水) 11:54:36
>>50
ですな。
というか、一般的に言う "mutex" に相当するものを、
Win32では "Critical Section" と呼んでいるから
混乱を招いているだけなんだけど。
52デフォルトの名無しさん:2009/09/23(水) 11:58:17
W32はCSもMutexも両方Mutexで特性が違うと考えるのが自然
53デフォルトの名無しさん:2009/09/23(水) 12:58:23
プロセスレベルで排他するからじゃなくて、
カーネルオブジェクトなのが原因なんじゃね?
54デフォルトの名無しさん:2009/09/23(水) 13:24:11
目的がそうだからしょうがない
5535:2009/09/23(水) 13:27:30
>>45
>てことで、>40にも書いたようにJavaのBlockingQueueの実装クラスが
>wait-freeでもlock-freeでもないのは、手抜きしているわけではなく
>そのように実装するのが不可能だからだ。

明解な説明です。理解できました。

>だからそれは "wait-free" って言葉の意味を誤解してるって。
>"wait-free" の wait とは、モニタ同期のwait()操作とかとは別物。

そのモニタ同期のwaiti()操作をイメージしていました。間違っていたんですね。
でわ、wait-freeの意味は、単純に「待ちが発生しない」へ改めます。
となると、lock-freeの意味も「待ちが発生する」に変わります。
ただし、どちらも「lock操作は不要」という特徴は共通している、と。
これでスッキリしました。

実は>>13,14,23のカキコ主だったのですが、lock-freeでは生産者-消費者モデルを
実現できない(畑違いである)ことが分かったので、次はwait-freeをと考えていましたが、
それも同様に誤解であることが理解できました。lock-free/wait-freeはスレッド間同期を
実現するプリミティブではない。それを実現するには、(lock操作を伴う)mutexや
モニタ同期(signal/wait)などを導入する必要がある、と。

lock-free/wait-freeの使い方について、ここ数日で急速にイメージが掴めてきた感覚です。
たいへんありがとうございました。>>all(特に>>15,32,40,45)
後は、Javaだけでなく、C/C++でも利用できる一般的なlock-free/wait-freeの実装技法が
確立し、標準ライブラリとして仕様化されることを願っています。
56デフォルトの名無しさん:2009/09/23(水) 13:37:41

lock-free queueは同期にも使えるよね?
5735:2009/09/23(水) 14:30:47
>>56
lock-free queueは「待ちが発生する」キューなので、スレッド間同期に
利用できるように見えるのですが、実際にはスピンによる実装なので、
「一般的な」アプリケーションでは利用できないと考えました。
言い換えると、lock-free queueだけで(mutexやモニタを一切使わずに)
「一般的な」アプリケーションを開発することは、現実的ではないという判断です。

もちろん、スピンが許されるケースや、mutexなどのオーバヘッドさえも
問題視される環境下では、lock-free queueを使わざるをえないケースも
存在していることは承知しています。あるいは、パフォーマンスクリティカルな
部分だけをlock-free queueで同期させ、残る大半ではmutexを使う設計も
あるでしょう。論理的にlock-free queueが同期に利用できないと
考えているわけではありません。
5835:2009/09/23(水) 14:39:25
(>>57に追記)

>>57の「一般的なアプリケーション」というのは、
生産者-消費者モデルで設計された、言い換えるとスレッド間同期が
前提となるマルチスレッドアプリケーションのことを指します。
たとえば>>13,14のアプリケーションではスレッド間同期が
必要ありませんから、lock-free queueを使用することができます。
(もちろんwait-free queueも使用できます。)
59デフォルトの名無しさん:2009/09/23(水) 17:49:20
CASとスピンは違うよ。スピンはロック解除待ちのループ。CASは更新中に割り込まれた場合のリトライ。
lock-freeの待ち時間は、よっぽどの酷い競合が起きたときに発生するにすぎない。一般的なアプリでは問題にならない。
そのような競合が起きるのは設計が悪いと思われる。
60デフォルトの名無しさん:2009/09/23(水) 18:05:46
>>55
http://www.ddj.com/hpc-high-performance-computing/208801974 これは?
俺はよく解んないからboost.threadのshared_mutexでmultiple-reader/single-writerやってるよ
マルチスレッドは奥が深いなぁ
61デフォルトの名無しさん:2009/09/23(水) 18:24:48
>>59
> スピンはロック解除待ちのループ。CASは更新中に割り込まれた場合のリトライ。

スピンロックは観察対象がロックオブジェクトで、CAS
は操作対象そのもの。

スピンロックは失敗時にはクリティカル領域に居る競合
相手の処理を促進する意味もあって普通ディスパッチす
ると思う(悪くすると飢餓状態に陥る)けど、CAS は領
域がそもそも小さいのですぐにリトライして ok ってこと?

相当限定的な使い方しか出来ない気がするなぁ…。「ス
レッドの状態を気にしなくて良い」んじゃなくて、気に
できないんじゃないの?
62デフォルトの名無しさん:2009/09/23(水) 18:29:10
>>60
boostのshared_ptrもlock-freeで実装されていなかったっけ?
ヘッダ見ると幸せになれるかもね
63デフォルトの名無しさん:2009/09/23(水) 19:23:00
スピン(に限らず)ロックは、ロックされていたら解放されるまでただ待つしかない
ロック保持者が何か処理に手間取って (ページングとか、割り込みとかで) 時間を取られたら、
それに引きずられて後続が全部渋滞してしまう
lock freeは、相手がすでに処理に入ってても我関せずで自分も処理に入ってしまい、
相手が何か手間取ってたら自分の方が先にCASを勝ち取り、次の処理に進めるというのが強み
負けた方は残念ながら最初からやり直し、今までやったことが無駄になるが、
今戦ってた相手はもう去ったし、次はたぶん成功するんじゃね?
次々に相手が現れていつまでも負け続けるようなひどい競合状態なら、普通のロックの方が良いらしい
負けたら同じ処理をもう一度やり直さないといけないという無駄がどうしてもあるし
64デフォルトの名無しさん:2009/09/23(水) 19:40:40
>>63
そういうlock-freeもあるけど、単純にアトミックアクセスだけで済ます場合もlockが
無いならlock-freeって呼ぶし(boost::shared_ptrとかがまさにそれ)、その場合は
lock-freeと言ってもバスロックを使ったりしてるからややこしいんだが、要するに、
何があってもデッドロックしないアルゴリズムならlock-free、ということだと思って
いるんだが
65デフォルトの名無しさん:2009/09/23(水) 19:45:19
デッドロックはまたややこしい話になると思うから置いとくとして
そういうのはやっぱりwait freeに分類すべきじゃないかな
wait freeもlock freeの一種といえばそうなんだけど
66デフォルトの名無しさん:2009/09/23(水) 20:01:02
lock-free : ロックせずにアクセスできる
wait-free : lock-freeの条件を満たしており定数時間で処理が完了する事が保証される
だけでそれ以外の要素は各実装による・・・じゃねーの
67デフォルトの名無しさん:2009/09/23(水) 21:09:37
まぁ>>63と全然違う仕組みのlock-freeも色々あるよってことで
68デフォルトの名無しさん:2009/09/23(水) 21:20:14
> 何があってもデッドロックしないアルゴリズムならlock-free

俺はこれが一番合点がいった。(dead)lock-free なわけ
ね。

…しかし「たまたま動いてたプログラムがより堅実に動
くようになります」っていうのはかなり微妙なメリット
な気もする(w
6935:2009/09/23(水) 23:21:08
>>59
CASとスピンとで内部の実装方法が異なるのは分かります。

# その意味では、>>57は以下のように訂正したほうがよいかもしれませんね。
#
# X:利用できるように見えるのですが、実際にはスピンによる実装なので、
# O:利用できるように見えるのですが、実際にはCASやスピンによる実装なので、
#
# X:もちろん、スピンが許されるケースや、
# O:もちろん、CASやスピンが許されるケースや、

ただ、>>3が指摘した生産者-消費者モデルで生産時間<<消費時間な場合を除き、
言い換えると生産時間>消費時間な場合、大半の状態でキューは空(から)のままです。
その場合、(キューを読み出す側の)消費者スレッドは、どのようにして待てば
よいのでしょうか?CPUを無駄にせず、いかにリトライをループさせるのでしょうか?
たとえば一般的なアプリケーションのキー入力「待ち」はCASやスピンで実装できますか?

実は、生産者-消費者モデルに関する同じような疑問は>>3だけでなく、前スレでも
たびたびカキコされていたのですが、レスがないか、あっても消費者スレッドを
待たせる方法に関する説明が無く、ずっと考え込んでいました。それが、>>45のレスで
クリアになったので、生産者-消費者モデル実現の前提となるスレッド間の「同期」に
ついては、lock-free/wait-freeは使えないと判断できました。

もちろん生産者-消費者モデルであっても、スレッド間の共有キューへの「排他(競合対策)」
については、lock-free/wait-freeを使用できます。一時的な待ちへの対応ですから。
スレッド間の「同期」と「排他」を意識的に区別して使い分けていることに注意してください。
70デフォルトの名無しさん:2009/09/24(木) 01:24:47
適当にスリープに落とせばいいんじゃ?
カーネルにスケジューリングを任せるより効率は若干落ちるが、高負荷時を見れば
lock-freeの恩恵が受けられるから悪くないかと。
スレッド間通信がボトルネックの外にあるなら、好きな方法でいいと思われ。
71デフォルトの名無しさん:2009/09/24(木) 01:47:24
すみません初歩的な質問で申し訳ないのですが,mutexで排他制御された場合、例えば
mutexlock();

A[0] = 0;

mutexunlock();

の様な場合、スレッドAはA[0]をアクセスして、スレッドBはA[100]をアクセスするとします。
その場合、スレッドBはスレッドAの処理が終わるまで配列Aにアクセスできないのでしょうか?
72デフォルトの名無しさん:2009/09/24(木) 01:50:07
>>71
そうなるね
73デフォルトの名無しさん:2009/09/24(木) 02:22:05
「の様な場合」なんていう他人に通じない省略しないで、
スレッドBの処理も書けばいいのに
74 ◆0uxK91AxII :2009/09/24(木) 04:50:22
>>71
//mutexlock();

A[100] = ~0;

//mutexunlock();

:b
75デフォルトの名無しさん:2009/09/24(木) 06:02:29
>>71です。
しょうもない質問をしてすみません。mutexでロックをかけた場合、配列にアクセスする場合はその間配列全体がアクセス禁止になるのか、
それともその一部のみ(例えばキャッシュライン分)がアクセス禁止になるのかを知りたかったのです。
アクセスできないとなると、 int D[10000]位確保されていたとして、
int *A,*B,*C;
A = &D[0];
B = &D[1000];
C = &D[2400];
のようにポインタでAの場所を指して、
スレッドA: D[0]〜D[1199]の内容を書き換え、スレッドB:D[1200]〜D[2399]の内容を書き換え、スレッドC:D[2400]〜D[3599]の内容を書き換え、
オーバーラップする領域はまずAの処理を優先するため、その領域を保護するためにmutexでロックをかけている間、
BはAの処理が終わるのを待たなければならないのは分かるのですが、CもAの処理が終わるまで待たなければならないのでしょうか?

Thread A:
for(i=0;i<1200;i++){
mutexlock(mu);
    A[i]=100;
mutec_unlock(mu);
}
Thread B:
for(i=0;i<1200;i++){
B[i]=200;
}
Thread C::
for(i=0;i<1200;i++){
C[i]=300;
}
76デフォルトの名無しさん:2009/09/24(木) 07:34:43
>>61
> 相当限定的な使い方しか出来ない気がするなぁ…。
> 「スレッドの状態を気にしなくて良い」んじゃなくて、
> 気にできないんじゃないの?

これ書いたの俺だけど、malloc() の内部処理辺りには
使えそうだと思った。それと類似して C++ の new() を
オーバーライドしといて予め準備しといたメモリプール
から取ってくるとかいうよくある奴。

例としてはそんなのでいいだろか? > 例を要求してた人
77デフォルトの名無しさん:2009/09/24(木) 08:25:29
>>75
その例の場合は素通り
配列が自動的にアクセス禁止になるわけではない
ThreadBもThreadCもmutexをロックしてどこからどこまで保護するのか明確にしなければならない
78デフォルトの名無しさん:2009/09/24(木) 09:17:59
>>77

ロックする範囲が限定されていれば、
他のスレッドは進行を妨げられずに処理できるのですね。
ありがとうございました。
7935:2009/09/24(木) 11:56:35
>>60
記事の紹介、ありがとうございます。読んでみました。

記事では、C++でlock-freeを使って生産者-消費者モデルを実現していますね。
以下はすべてC++のWaitFreeQueueクラスとして実装されています。

・まずlock-freeで「排他」を実現するキューを実装。
 この時点では「排他」だけですから、スレッド間の「同期」は実現できていません。
・次に、キューが空である間、消費者スレッドをループさせ続けることで「同期」を実現。
 この方式では、キューが空であればCPUを100%消費します。
 ==> NATIVE_POOLING方式
・続いて、キューが空である間、消費者スレッドをスリープさせ続けるループを
 組むことで「同期」を実現。 ==> SLEEP方式
・最後に、BOOSTのcondition(timed_wait/notify操作)を使う事で、
 「同期」を実現。==> TIME_WAIT方式

(続く)
8035:2009/09/24(木) 11:59:49
(>>79の続き)

このC++ by DDJ実装と、>>40が紹介してくれたJavaの実装とを比較すると、
lock-free/wait-freeの意味に違いがあるように感じられました。
C++ by DDJ実装のTIME_WAIT方式は、JavaであればBlockingQueueクラスに相当しますが、
>>40では、BlockingQueueクラスは(同期の実現はモニタ使用が前提だから)
lock-free/wait-freeではない、と定義しています。

これらの一見矛盾しているように見える事柄を、自分なりに以下のように解釈してみました。

・lock-free/wait-free単独では「同期を実現できない」
・ただし、lock-free/wait-freeとスリープ(あるいはモニタ/conditionなど)とを組み合わせた制御を
 アプリケーション側で(たとえばクラスとして)実装することで「同期を実現できる」

誰も皆「排他」に関しては「実現できる」と見解は一致していますが、
この「同期」が「実現できる/できない」という解釈に関しては、人によって見解が
分かれているように思えます。違いは、「スリープ/モニタ/conditionなど」の使用を含めて
「できる」とする考え方と、それらは純粋なlock-free/wait-freeではない、とする考え方です。
難しい論争で、技術的な課題でもありませんから、私もこれ以上の考察は止めにします。
8135:2009/09/24(木) 12:10:08
>>70
レスありがとうございます。

>>80の最後で書いたように、lock-free/wait-freeとスリープとを組み合わせた制御を
アプリケーション側で実装することによって「同期」は実現できますね。

# せっかく>>60がDDJの記事を紹介してくれていたのに、それを読まずに>>69
# カキコしてたのが、まずかったと反省しています。余計な手間をとらせてごめんなさい。
82デフォルトの名無しさん:2009/09/24(木) 12:24:59
リング遷移よりはスピンした方がいいとか、ある程度待っても何も来なかったら
スリープとか、待機時の特性をアプリケーションがチューニングするやり方に
なるのは、ハイパフォーマンス向けだと利点と言えるのでは。
まぁ、リング遷移が気にならない状況ならカーネルに任せていいと思うけど。
とりあえず、スピン待機は立派な同期だよ。CPU使用率をやけに気にしてるけど、
MP向けだとスピンじゃないと話にならないことも多い。
8335:2009/09/24(木) 14:21:36
>>82

(CASやスピンを用いた)lock-free単独による同期については、メニーコア、
あるいはその先(未来)にある超並列な世界であれば、並列システム全体から
見ると個々のコア(CPU)の無駄は無視できます。だから、その時代になれば
「lock-free単独による同期が常識」となっている可能性は十分に予測できます。
もしかすると、現在でも>>82が主張されているMP(?)向け用途、それに
HPC(High Preformance Computing)やCELLのプログラマにとっては、
既に「lock-free単独による同期は常識」なのかもしれませんね。

ただし、現在のPC向け汎用CPUはシングルコアかせいぜい4コアが主流です。
その世界では、いかに個々のコアを無駄無く使いつぶすかが、
性能設計上の大きな課題になります。ですから、現時点では、
「lock-free単独による同期は一般的ではない」、言い換えると、
一般アプリケーションにおいては「スリープなどと組み合わせない限り
(単独の)lock-freeでは同期は実現できない」と解釈しています。

論理的にはCASやスピンでも同期は実現可能である(立派な同期である)。ただし、
一般的な多くのケースにおいては、その方式は現実的ではないということです。
これもまた「できる/できない論争」の一種ですよね。
84デフォルトの名無しさん:2009/09/24(木) 14:28:13
デュアルコアでさえスピンは使うって。

lock-free queueのcalleeが同期の機能を持ってるか、にこだわってるの?
callerが同期処理をしなきゃならない、だとしても、lock-freeで同期してることに
なると思うけど。そうじゃないなら、シーケンスロックはロックの機能を持たない
とかいう変な話になるぞ?
つーか、ノンブロッキング同期の一種だぞ、lock-freeもwait-freeも。
8535:2009/09/24(木) 14:51:24
>>84

同じ「待ち」でも、「排他(ロック)」と「同期」は別のものです。

「排他」による待ちは一時的です。もしもそれが長時間継続するようであれば、
それは「設計が悪い」のです(一般にはバグとして扱う)。
それに対して「同期」の継続時間は不定です。
最も長いケースでは、システム全体が終了するまで「待ち」状態が継続します。

また、共有キューを用いた「同期」を実現するには「排他」も必要です。
ただし、だからといって「排他」だけでは「同期」は実現できません。

「排他(ロック)」と「同期」を区別して、考え直してみてください。

lock-freeには「排他」機能があります。ですから「デュアルコアでさえ
スピンを使う」ことはあります。でも、lock-freeを単独で「同期」に
用いるのは現実的ではないと言っています。

というか「できる/できない論争」は止めにしませんか?私はこれで降ります。
86デフォルトの名無しさん:2009/09/24(木) 15:05:18
> 一般的な多くのケースにおいては、その方式は現実的ではないということです。

ここの認識が勘違いしてると思うけどなぁ。
まぁ降りるならどうぞ。
87デフォルトの名無しさん:2009/09/24(木) 16:28:41
lock-free queueの話で同期の話が出てくる時点で何かおかしい気がしている
lock-free queueってのはこういうものだと認識しているのだけど…↓

マルチスレッドにおけるQueueのpushとpopの処理では、内部の変数の更新が衝突すること
によって破壊されてしまう場合があるため、何かしらの機構を備えておく必要がある。
mutex等による排他制御ではコンテキストスイッチが発生し、それは時間的にシビアな場面
においては非常に遅くなる場合がある。
そのためコンテキストスイッチさせないようにあの手この手を尽くして
(mutex等排他制御のためのプリミティブが使われていない)lock-freeなものを作る場合がある。
lock-free queueでは複数のスレッドからQueueに対してpush/popされても、内部でmutex等
による排他制御は行われず、コンテキストスイッチが起こらないため、複数スレッドから
の高速なデータのpush/popが期待できる。

↑何か間違ってる?
Queue(待ち行列)という特性を見るかぎり、Queueを使った同期ってのがどういうものか
イマイチ解らない。
88デフォルトの名無しさん:2009/09/24(木) 16:51:14
if(v.empty()){/*待機コード*/}
int i=v.pop();

例えばこれも同期
89デフォルトの名無しさん:2009/09/24(木) 16:52:09
ifじゃなくてwhileだった
90デフォルトの名無しさん:2009/09/24(木) 17:23:43
>>88
それって、Queueを使うためにmutexやスピンロック等を使った同期であって、
Queueを使った同期ではないような…
もし仮にそのことをQueueを使った同期と言っているのであれば、それとlock-free queueとは
関連性薄くない?(べつにbool値のflagだとしても議論できるし)

もしかしてQueueとかもう話題的にあんまり関係なくて、
単純に、スピンロックやmutex等の排他制御、CASはそれぞれどういう時に便利ですか?
って議論だったりする?
91デフォルトの名無しさん:2009/09/24(木) 17:47:00
>>88
empty()とpop()が別だから、複数スレッドだとrace conditionになるね。
92デフォルトの名無しさん:2009/09/24(木) 18:03:19
どう見てもmutexもスピンロックも使ってないし、empty()じゃなくなった後に
empty()がtrueにならないことが保証されてるqueueなら競合もしないよ
93デフォルトの名無しさん:2009/09/24(木) 18:08:41
お互いに勝手なコンテキストを想定して話すから、会話が成り立ってない。
94デフォルトの名無しさん:2009/09/24(木) 18:13:27
・読み手/書き手は単数なのか複数なのか
・一般例なのか状況限定の例なのか
・empty()はロックしないことを保証しているか(lock-freeならしているだろうけど)

こういう重要な条件をお互いに伝える気も読み取る気も感じられない。
9587:2009/09/24(木) 18:25:37
while (v.empty()){}
↑こういうコード(ある状態が真になるまでループする)がスピンロックなのかと思ってた。
>>92みると違うみたい?
96としあき:2009/09/24(木) 18:34:00
> こういう重要な条件をお互いに伝える気も読み取る気も感じられない。
97デフォルトの名無しさん:2009/09/24(木) 18:50:40
>>95
それロックじゃないでしょ
98デフォルトの名無しさん:2009/09/24(木) 23:38:03
空気読まずに lock-free C++ vector の論文貼るね。既出ならメンゴ。
ttp://www.research.att.com/~bs/lock-free-vector.pdf
2006 年、Bjarne Stroustrup も噛んでる。なかなか性能いいみたい。
9935:2009/09/25(金) 02:21:30
>>87

lock-free queueを実装する視点であれば、その認識は間違っていないと思うよ。

>>90
>単純に、スピンロックやmutex等の排他制御、CASはそれぞれどういう時に便利ですか?
>って議論だったりする?

自分はlock-free queueを使う立場だから、そういう視点で>>81まで議論を続けてきました。
で、その後から議論が拗れてしまったわけですね。

何が原因かを考えました。自分は、(共有キューの競合による破壊を防ぐ為の)「排他」制御の為に
スピンを「使う」ことは「一般的である」けれど、キューが空の場合に「待つ」、いわゆる
「同期」の為にスピンを「使う」のは(汎用PC/CPUの世界では)「一般的ではない」という立場。

それに対して、いや、キューが空で「待つ」場合にも、スピンを「使う」のは(汎用PC/CPUの
世界であっても)「一般的である」というのが、相手の立場。

ある事柄に対して、それが「一般的である/ではない」という解釈は、一般常識論ですから、
それぞれの立場によって異なるのが当たり前です。そんな両者が納得できる結論を導くのは難しい。
だから、>>85では、これ以上議論を続けても不毛なので止めることを提案しました。
100デフォルトの名無しさん:2009/09/25(金) 13:02:48
できません

できます

一般的じゃないからできないようなもんです

ハァ?

って流れに見えた
101デフォルトの名無しさん:2009/09/25(金) 15:30:44
私はこれで降ります

何が原因かを考えました

提案しました

ワロタ
102デフォルトの名無しさん:2009/09/26(土) 14:00:48
>>87
多分間違っていると思うよ

コンテキストスイッチは関係ない。
lock-free なキューのメリットは、lock-free でないキューより
(ロックしないから)アクセスの並列性が高まること。
もちろん競合するときには性能が落ちるけど、平均的には
性能向上が期待できる。
103デフォルトの名無しさん:2009/09/26(土) 20:19:00
アクセスの並列性ってどういうこと?
それが高いと何がうれしいの?
104 ◆0uxK91AxII :2009/09/26(土) 20:34:29
こんなケースで、こういうlock-freeなのを実装したら、
これだけパフォーマンスが向上しました・
...みたいなのを挙げてみてほしい。

どうでも良いけど、jemallocでも、spinlockしているね。
105デフォルトの名無しさん:2009/09/26(土) 21:38:58
>>103
ロックは重い処理だから、それなしにCAS等の手法で数十ステップで収まるloc-freeは
軽い(逐次実行時間が短い)ってことを言いたいんだろ。

ただ、コンテクストスイッチは関係ないと言い切っちゃうのは、もう......だなw
106デフォルトの名無しさん:2009/09/26(土) 22:37:25
lock-freeの定義が各人の頭の中にしかないから1000までこの話題でも結論は出ない(キリッ
107デフォルトの名無しさん:2009/09/26(土) 23:05:40
まず、スピンロックとlock-freeにおけるCASの違いは

スピンロックは、単純に同じ動作(CAS)を再試行する
lock-freeの実装では、単純に値を読み直す場合や全ての動作を最初からやり直す場合等いろいろあるが
とにかく、「同じ値で再度CASを実行する」ということはしない。

wait-freeは、上記の「CASの再実行」が起こらない、ということだから
言い直せば、retry-freeとでも言えるのかも知れない。
108デフォルトの名無しさん:2009/09/26(土) 23:10:11
あと、上のほうで「CASを使わなくてもメモリバリアがあれば云々」という話があったようだが
CASが重いのは、CASに含まれるメモリバリア(バスロック)動作が重いのが理由なのだから
CASを無くしたからってメモリバリアが必要なら、たいしてメリットは無くなる。

もし、「メモリバリアも無くしてかつwait-freeな実装が可能」というなら話は別だが。
109デフォルトの名無しさん:2009/09/27(日) 09:14:18
>>103
ちょっと古いけど、
http://www.ibm.com/developerworks/jp/java/library/j-jtp07233/index.html
のスケーラビリティの問題あたりから下の部分はどう?
110デフォルトの名無しさん:2009/09/27(日) 15:28:18
>>108
> CASが重いのは、CASに含まれるメモリバリア(バスロック)動作が重いのが理由なのだから
メモリバリアとバスロックは別の概念だぞ。
たとえばIA-64には、メモリバリア無しのCAS命令(ニーモニック:cmpxchg)と、
メモリバリア有りのCAS命令(cmpxchg.acq や cmpxchg.rel)がある。

そもそも、メモリバリア自体はそこまで重い操作じゃない。
特に、C++0xでの memory_order_acquire, memory_order_release に相当する
メモリバリアは、自身のスレッド内での順序づけを保証するだけなので、
他CPUとの通信を必要としないためコストもかなり小さい。
で、これまで話題になっているwait-freeなlinked queueなど、
多くのlock-free, wait-freeアルゴリズムの実装では、
この acquire, release 相当のメモリバリアで十分だ。
111デフォルトの名無しさん:2009/10/01(木) 09:08:46
見よう見まねでスピンロック実装して動作テストしたら標準のCriticalSectionより劇おそだったのは苦い思い出:プライスレス(´・ω・`)
112デフォルトの名無しさん:2009/10/01(木) 10:15:16
Win32のCriticalSectionの激速の理由は
プロセッサを判定して、可能ならばunlockにmovを使ってバスロックを避けているから

と俺は勝手に想像している。
113 ◆0uxK91AxII :2009/10/01(木) 18:03:15
push/popを必要最低限にして、
適宜pause(rep; nop)を入れれば良いだけ。
114234:2009/10/01(木) 20:17:23
>>112
コンテキストスイッチが無いときはカーネルに入らずに、単にロックカウントをアップしてるだけだからだよ。
115デフォルトの名無しさん:2009/10/01(木) 21:48:37
>>114
いやそんなの当たり前だし。

「単純なスピンロックより速い(>>111)」理由が何故か?だよ。論点は。
116デフォルトの名無しさん:2009/10/01(木) 22:46:40
>>115
非コンテキストスイッチング時はアセンブラで10数命令しか実行して無いんだから速いよ。
それに>>111のコードを見なければなんともいえない。
117デフォルトの名無しさん:2009/10/01(木) 23:01:29
だから、その命令の中に、lock xadd とかの重い命令があるんだよ。
118デフォルトの名無しさん:2009/10/01(木) 23:10:26
コンテキストスイッチが無いから速い、とか
アセンブラで10数命令だから、とか

偉そうな態度の割に、底が浅すぎる。
119デフォルトの名無しさん:2009/10/02(金) 00:06:49
お前も相当えらそうだが。
120デフォルトの名無しさん:2009/10/02(金) 00:26:57
無知が知ったかぶって偉そうにしながら恥を晒してるのとは違うみたいだけど。
121デフォルトの名無しさん:2009/10/02(金) 00:44:09
間違っているというだけで何が間違っているか書かないやつは大抵ハッタリだわな。
122デフォルトの名無しさん:2009/10/02(金) 00:44:47
>>121
それ正解。
123デフォルトの名無しさん:2009/10/02(金) 00:49:28
void __stdcall trylock(volatile int *spin) {
__asm { mov ecx, spin;
mov edx, 1;
xor eax, eax;
lock cmpxchg [ecx], edx;
}
}
void __stdcall unlock(volatile int *spin) {
__asm { mov ecx, spin;
xor edx, edx;
mov eax, 1;
lock cmpxchg [ecx], edx;
}
}
void __stdcall trylock_nlk(volatile int *spin) {
__asm { mov ecx, spin;
mov edx, 1;
xor eax, eax;
cmpxchg [ecx], edx;
}
}
void __stdcall unlock_nlk(volatile int *spin) {
__asm { mov ecx, spin;
xor edx, edx;
mov eax, 1;
cmpxchg [ecx], edx;
}
}
void __stdcall unlock_nbl(volatile int *spin) { *spin = 0; }
124デフォルトの名無しさん:2009/10/02(金) 00:50:21
DWORD readtsc() {
DWORD v;
__asm {
rdtsc;
mov v, eax;
}
return v;
}
int main() {
const COUNT = 1000;
CRITICAL_SECTION cs;
InitializeCriticalSection(&cs);
volatile int spin = 0;

int st = readtsc();
for (int i = 0; i < COUNT; ++i) { EnterCriticalSection(&cs); LeaveCriticalSection(&cs); }
printf("%u clocks at %s\n", readtsc() - st, "CriticalSection");
st = readtsc();
for (int i = 0; i < COUNT; ++i) { trylock(&spin); unlock(&spin); }
printf("%u clocks at %s\n", readtsc() - st, "CAS");
st = readtsc();
for (int i = 0; i < COUNT; ++i) { trylock_nlk(&spin); unlock_nlk(&spin); }
printf("%u clocks at %s\n", readtsc() - st, "CAS(lockプリフィックス無し)");
st = readtsc();
for (int i = 0; i < COUNT; ++i) { trylock(&spin); unlock_nbl(&spin); }
printf("%u clocks at %s\n", readtsc() - st, "CAS(movでunlock)");
}
125デフォルトの名無しさん:2009/10/02(金) 00:51:21
ほれ、ベンチ用意したぞ。
シングルスレッドで、ロック獲得が必ず成功する場合の数字のみ。
実際はカウンタ持ってるから単純なcmpxchgじゃなくxaddで正負と0を駆使して判定してるだろうし
ロックを獲得できなかった場合にブロックに移行する処理もあるだろうけどな。

まあ見難いが、面倒くさかったから
TABのインデントは見たい人が自分でやってくれ。
126デフォルトの名無しさん:2009/10/02(金) 00:54:44
これでもまだ「コンテキストスイッチが」「命令数が」と言いたいなら
ご自由にどうぞ。
127デフォルトの名無しさん:2009/10/02(金) 00:58:52

しかしお前がどのレス書いたやつで何を主張したいのかがわからん。
128デフォルトの名無しさん:2009/10/02(金) 01:03:20
実行してみなきゃ結果の意味するところもわからんからね。
まあ俺は>>112>>115>>117とかだが。

関係ないが、stdcallとか、全然意味なかったな。
全部展開されてるし。
しかも、Enter/Leaveもレジスタにコピーされてレジスタ間接コールになってる。
129128:2009/10/02(金) 01:04:01
>>123-124が俺な。
130128:2009/10/02(金) 01:27:59
まあ一応、俺の手元での数字を出しとく。
rdtscで計ってるので、別プロセスに割り込まれない限り
何回やっても似たような数字になる。

18065 clocks at CriticalSection
39098 clocks at CAS
13700 clocks at CAS(lockプリフィックス無し)
19025 clocks at CAS(movでunlock)

1番上が、単純にCriticalSectionをEnter/Leaveしたもの。
次が、「教科書通り」のCAS(lock+cmpxchg)を使ったスピンの取得と解放。
おそらく、>>111もこれに似たコード(取れない時のループは無し)を書いたと思われる。
3番目は、上のコードから、バスロックを除いたもの。バスロックのコストを示すため。
4番目が、>>112に述べた、unlock時のバスロックを避けるようにしたもの。

結論としては、>>112の推測が確信に変わっただけ。
131 ◆0uxK91AxII :2009/10/02(金) 11:18:35
spinlockの話題>>111
が、CASにすり変わっている件について。
132デフォルトの名無しさん:2009/10/02(金) 12:33:54
「教科書通りのスピンロック」って、普通は
xchg (test-and-set)でロックを取って、movでアンロックじゃねーの?
それとも最近の教科書は test-and-set より先に
compare-and-swap を教えるのかな?
133デフォルトの名無しさん:2009/10/02(金) 13:15:17
一般のプロセッサでxchgが1バスサイクルで実行される保証なんて無い。
というより、普通は読みと書きになる。(x86が特殊なだけ)
だから、ロックを取得するにはCASが必要。
134デフォルトの名無しさん:2009/10/02(金) 13:17:13
あ、ごめん
TASならば確かにCASである必要は無いね。
135デフォルトの名無しさん:2009/10/02(金) 13:22:36
だけど、「アンロックがmovが普通」は違う。

理由は
http://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%94%E3%83%B3%E3%83%AD%E3%83%83%E3%82%AF#.E6.9C.80.E9.81.A9.E5.8C.96
のように、
movだと、直前のクリティカルな部分への書き込みが他のプロセッサに伝わる前に
アンロック処理のmovの書き込みが他のプロセッサに伝わる可能性があるため。
136デフォルトの名無しさん:2009/10/02(金) 13:52:10
>>135
それはメモリバリアの問題であって、movかCASかは関係ない。
mov命令がreleaseメモリバリア効果を持っていればそれで十分だし、
逆に>110で挙げたようなメモリバリア無しCAS命令では不十分。
137 ◆0uxK91AxII :2009/10/02(金) 13:54:13
>>135
それはspinlockを使う側が考慮する問題であって、
作る側は無視して良い。
138 ◆0uxK91AxII :2009/10/02(金) 13:59:49
W2kSP4, Athlon 64 X2 3800+, VC6SP6+PP5, 最適化無し
50239 clocks at CriticalSection
49180 clocks at CAS
21132 clocks at CAS(lockプリフィックス無し)
32103 clocks at CAS(movでunlock)
139デフォルトの名無しさん:2009/10/02(金) 14:24:08
>>136
それがメモリバリアの問題だっていう、そんなことわかってるよ。
そして、「一般的なmov」はメモリバリアの機能など持っていない事
さらに、「(次に書く)このスレで"一般に"用いられるCASという用語」はメモリバリアを持っているもね。

もちろん、CASというのがメモリバリアとは直接は関係ないってことだって充分知ってるよ。
(そうでなければ、lockなしのcmpxchgなんてもの出すわけ無いだろ)
だけどこのスレで一般的にCASと言ったら
「アトミック操作で用いる事が可能なCAS」のことが普通だろうに。
140デフォルトの名無しさん:2009/10/02(金) 14:28:11
「一般的なmov」つまり、普通のロード/ストア操作はメモリバリアを持っていないのだから
普通のスピンロックの実装では、アンロック処理に
movではなくメモリバリアを持ったTASやCASを使う。
(それらはロック獲得処理の段階で存在が示されている)

だから「普通はmovでアンロック」などということは有りえない。
141デフォルトの名無しさん:2009/10/02(金) 14:37:59
>>140は「教科書では」ね。
142デフォルトの名無しさん:2009/10/02(金) 14:53:16
Windows Vista 64bit SP1, Core2DuoE6750, Microsoft Visual Studio 2008(VC Version 9.0.21022.8 RTM)

/O2 /Ob2 /Oi /Ot (実行速度で最適化、インライン関数は展開可能な関数すべて展開)
101192 clocks at CriticalSection
67904 clocks at CAS
20424 clocks at CAS(lockプリフィックス無し)
88688 clocks at CAS(movでunlock)

/Od /Ob1(最適化なし、インライン関数は展開しない)
108568 clocks at CriticalSection
99976 clocks at CAS
24184 clocks at CAS(lockプリフィックス無し)
65280 clocks at CAS(movでunlock)

>>130の結果が謎すぎる
143デフォルトの名無しさん:2009/10/02(金) 15:17:56
>>139
アトミック性とメモリバリアは別の概念だぞ。
CASがアトミックなのは当たり前であり、俺もそんなことに
文句をつけているわけじゃない。

x86におけるlockプレフィックスのないcmpxchgは
SMP環境ではアトミック性が保証されないから
(正しい意味での)CASとは言えない。
でも、>110で挙げたのは「アトミック性は保証されているが
メモリバリア効果を持たないCAS」だ。

CASとは「あるメモリ位置に対する内容の取得・比較から代入までが
アトミックに行える操作」であり、メモリバリア効果、つまり
「前後の命令との間でリオーダーを行わないという保証」は必須ではないと
俺は言っている。
# 実際に、C++0xのatomicライブラリではそのように定義されているし。

「普通のロード/ストア命令はメモリバリアを持たない」と言うのなら、
メモリバリアを持つロード/ストア命令を定義して、それを使えばいい。
何故わざわざCASやTASのような複雑な操作を持ち出す必要がある?

ちなみに、x86のmov命令は(初期のバグ持ちプロセッサを除いて)
デフォルトでreleaseメモリバリア効果を持っているぞ。
144デフォルトの名無しさん:2009/10/02(金) 15:36:13
はいはいごめんよ。
全部俺が悪かったよ。
145デフォルトの名無しさん:2009/10/03(土) 09:36:48
ttp://d.hatena.ne.jp/bsdhouse/20090720/1248085754

ここが勉強になった。
146デフォルトの名無しさん:2009/10/03(土) 10:16:52
ちらっと見ただけなんだけど、「volatile つけた変数に排他性は無いよ」
ってことをグダグダ言ってるみたいだけど、そんなの当たり前では?

都市伝説もくそもねーよ
147デフォルトの名無しさん:2009/10/03(土) 11:06:13
acquire/releaseバリヤって、
「そのスレッドでのメモリアクセスについて」限定?
↑のスライドだと前後の命令を・・・となってるけど
148デフォルトの名無しさん:2009/10/03(土) 11:36:54
当たり前よ
っつかどういう意味で聞いてる?
149デフォルトの名無しさん:2009/10/03(土) 11:37:10
菊池バリヤー!
150デフォルトの名無しさん:2009/10/03(土) 16:40:11
「バリア」って概念には
「メモリアクセスがコーダーが記述した”順”に実行されることが
保証される」っていう以上のものは含まれていない(例えばインク
リメント操作がアトミックになることまでは保証されない)と認識し
ているのですが。当たってます?
ネットに散らばっている情報にはブレがあると思えるし、正直、
勉強不足ではっきりと分からないところがあるので質問します。
151デフォルトの名無しさん:2009/10/03(土) 18:09:38
>>150
それで正しい。
ちなみに、マルチスレッドの世界には「バリア同期」っていう全然別のものもあるので、
メモリバリアのことは「メモリフェンス」と呼ぶようにした方がいい。
152デフォルトの名無しさん:2009/10/03(土) 19:15:56
>>151
ありがとうございます。頭の中がすっきりしました。
153 ◆0uxK91AxII :2009/10/03(土) 21:22:33
どうでも良い事だけど。

spinlockを奪い合った場合、
先に取ろうとした方が取れず、
後から取ろうとした方が取れたとしても、
動作としては正しいんだよね。
154デフォルトの名無しさん:2009/10/03(土) 21:37:43
spinlockはアンフェアだからそれで正しいね。
155デフォルトの名無しさん:2009/10/03(土) 22:29:57
>spinlockはアンフェアだからそれで正しいね。
それは答えになってるのか??
156デフォルトの名無しさん:2009/10/03(土) 23:21:32
間違いではない=正しい
という論理がわからないのか?

どうしょうーもねーな
157デフォルトの名無しさん:2009/10/03(土) 23:32:43
正しいのか?って言ってんじゃなくて
答えになってるのか?
って言ってんだけど。
158デフォルトの名無しさん:2009/10/04(日) 00:51:01
答えにはなっているように見える。「正しいのか?」という問いに「正しい」と答えている。
その答えが正しいのかどうかは別の話。
159デフォルトの名無しさん:2009/10/04(日) 03:29:21
160デフォルトの名無しさん:2009/10/05(月) 13:09:01
>>155
説明になっているかどうかはともかく
答えにはなっていると思うんだが。
161デフォルトの名無しさん:2009/10/13(火) 02:20:13
火元の人
 やり方が理解できない質問者
 俺に分からないならこのスレにも理解できる奴いないんじゃね、とか思っていて、
 それが態度にも滲み出ている

煽る人
 分かってるつもりだけど分かってないで煽り続ける
 こいつを見た火元は「やっぱり分かってる奴いないんじゃないか」と思いこむ

住人タイプA
 一目で分かるがお前の態度が気に入らないしコード示すのマンドクセ
 つーかこの説明で分かれボユゲ

住人タイプB
 みんな何言ってんだかわかんね

ちょっと違うけどこのパターンに似てる
162デフォルトの名無しさん:2009/10/14(水) 09:48:32
posix準拠のオーソドックスなやり方しかしない俺にはこのスレは不要なようだ
おまえら何言ってるかわかんねぇーしw
163デフォルトの名無しさん:2009/10/14(水) 10:36:30
>>162
自分からPOSIXスレッドとかに関連したネタをふればいいんじゃないかな?

まあ正直なところ、ここは相談室スレなんだから、あまりにもハードウェア寄りな専門知識が
必要な話題については、できれば「並列化について語る」スレで熱く語ってくれって感じはしてる。
あっちはハード(マルチプロセッサ/マルチコア)全然オケーなスレなんだから。
164デフォルトの名無しさん:2009/10/14(水) 13:09:43
単に自分の付いていけないレベルの話題を締め出したいだけに見える
165デフォルトの名無しさん:2009/10/14(水) 13:35:03
ということにしたいだけにも見える
166デフォルトの名無しさん:2009/10/14(水) 21:17:55
つーか俺はposix準拠な世界で生きてきたので。
おまえらよくposix非準拠な話題で盛り上がれるなーw
167デフォルトの名無しさん:2009/10/14(水) 22:48:54
>>166
CASやメモリバリアなどはpthreadライブラリの実装者にとっても
必須の知識だよ。
168デフォルトの名無しさん:2009/10/14(水) 23:10:22
>>167
利用者にとっては?
169デフォルトの名無しさん:2009/10/15(木) 03:21:14
POSIX厨としか言いようがない
170デフォルトの名無しさん:2009/10/15(木) 08:47:16
>>169
POSIX使うのが普通じゃないの?
171デフォルトの名無しさん:2009/10/15(木) 13:13:35
pthreadにはアトミック操作が定義されてないから、
単なるカウンタのインクリメントでも
いちいちロックしなきゃならんのが嫌だ。
172デフォルトの名無しさん:2009/10/16(金) 00:37:47
なんでPOSIXで厨なんだよ(´・ω・`)
173デフォルトの名無しさん:2009/10/16(金) 02:28:34
POSIXスレッド以外の話題ってだけで叩くなら完全に厨だろ
174デフォルトの名無しさん:2009/10/16(金) 06:51:32
他人を厨と決めつける人が厨に見える
175デフォルトの名無しさん:2009/10/16(金) 08:03:36
何でも鸚鵡返しすれば反論になると思ってるだろ
176デフォルトの名無しさん:2009/10/16(金) 08:04:58
baka
177デフォルトの名無しさん:2009/10/16(金) 08:09:28
pthread地獄 part 2
http://pc12.2ch.net/test/read.cgi/unix/1166620307/

ここへ行けばいいのに
178デフォルトの名無しさん:2009/10/17(土) 03:19:26
          /\              ┌┐            ┌┐       ___ ___
        / __ \       /\  ..||..  /\       ||    ___ \\ \
      / / .\ \     \  \ .||. /  / ┌──┘└──、\\  ̄  ̄
    / /     .\ \     \/ .||. \/   └──┐┌─ 、| |__|
  / / ┌──┐.\ \  ┌───┘└───┐      .||  ||
 ..\/   └┐┌┘  .\/ └───┐┌───┘     / /  ||
        ┌┘└┐          /\ .||. /\      / /   / /
        └┐┌┘        /  / .||. \  \   / /   / /
      ┌─┘└─┐     \/  ..||..  \/   \/    / /
      └────┘          └┘              \/

                                           ....、
....................--------、,           i~゙7   r‐ッ    !゙゙.!       ! !
: !―――;;;;;;''''''''ゝ ,,ノ゛    ._   / ./   .,! .,!    ! !  .,..............! ヽ..........-、
      | |./ /      .l、,`''-./ ./    ! !    | |   ――ーッ .iー''''''''i |
      | l'-‐゛        `゙ッ  .ゝ、   .| |    | ,!      ./ ./   ! !
     ../ .,!             /.,r'"\,/  .!ー′   ./ .,!     . / ./    | │
    .,./ ./         ,..‐" /            . / /     ./../     ./ .l゙
  .r'"./           ゝ/゛          : ,,-'゛./    .〈 /    .'|,゙,゙,,,, "
   .`゛                        ゙'''"
179デフォルトの名無しさん:2009/10/20(火) 15:39:31
その “全米” はグアム島を含むのでしょうか。
180デフォルトの名無しさん:2009/10/20(火) 19:08:01
グアム、どうなんだろ。州に昇格すればいいのに。まあ、しないだろうけど。
181デフォルトの名無しさん:2009/11/03(火) 00:02:53
スレッドを終了させるときは_endthreadexじゃなく
そのままreturnでもいいのか?スタックの開放されない?
182 ◆0uxK91AxII :2009/11/03(火) 00:28:01
良い。
mallocで取ってきた領域をfreeしなくて良いのと同じくらいに。

スタックとやらは、_endthreadexとは無関係。
183デフォルトの名無しさん:2009/11/03(火) 00:59:57
freeしろよ
184デフォルトの名無しさん:2009/11/03(火) 01:16:04
スレッドに強くないのに書き込んでみる。

ttp://msdn.microsoft.com/ja-jp/library/hw264s73(VS.80).aspx
>ただし _endthread または _endthreadex は、_beginthread や _beginthreadex の
>パラメータとして渡されたルーチンからスレッドが戻ると自動的に呼び出されます。

ってことで、returnすれば問題ないかと。
どちらかというと

>_endthread と _endthreadex によって、C++ デストラクタはスレッドで保留状態になり、呼び出されません

なので、呼ばないほうが好ましいような。
185 ◆0uxK91AxII :2009/11/03(火) 01:52:01
182は無かった事にしてください。
んゆ。
186184:2009/11/03(火) 14:42:55
スレッドに強い人に補強して欲しいのだけど、それとも184の認識で問題なし?
187 ◆0uxK91AxII :2009/11/03(火) 17:34:11
Microsoft Visual Studio\VC98\CRT\SRC\THREADEX.C

んゆ。
188デフォルトの名無しさん:2009/11/03(火) 17:55:09
問題なし
189デフォルトの名無しさん:2009/11/03(火) 22:08:15
スレッド識別子って何なんだ?
何に使うの?
190デフォルトの名無しさん:2009/11/03(火) 22:25:48
殺したり、止めたり。
191デフォルトの名無しさん:2009/11/04(水) 21:43:06
他スレッドの変数の中身知ることってできないかな?
192デフォルトの名無しさん:2009/11/04(水) 21:55:11
メモリ空間は共有しているので、アドレスがわかれば普通に参照できる。
193デフォルトの名無しさん:2009/11/05(木) 12:32:06
win32のインターロックをクリティカルセクションと
同じように使ったら早くて驚いた。

両者の内部的な違い・利点・欠点てなんですかね?
194デフォルトの名無しさん:2009/11/05(木) 14:06:45
そもそも用途が違うんじゃない?
インターロックは変数1個ぶんの更新しかできないでしょ?

インターロックを使ってクリティカルセクションと同様のものを作ることはできるだろうし、
クリティカルセクションを使ってインターロックと同様のものを作ることもできるだろうけど、
そういう話?
195デフォルトの名無しさん:2009/11/05(木) 14:31:15
インターロック一発で出来ることならインターロックで。
196デフォルトの名無しさん:2009/11/05(木) 14:54:32
win32のクリティカルセクションは衝突しなければインターロックと同じくらい早いんだなこれが
197デフォルトの名無しさん:2009/11/05(木) 16:01:33
いや倍くらいは遅いだろう。
198デフォルトの名無しさん:2009/11/05(木) 16:15:02
んだ。インターロックで済むならそれが数倍早い。
199193:2009/11/05(木) 19:29:23
今以下のクラスでクリティカルセクションと同じように扱ってテストしてるんだ。
class InterLock
{
private:
LONG m_Flag;
public:
void Enter()
{
while(InterlockedCompareExchange(&m_Flag,1,0)) Sleep(0);
}
void Leave()
{
InterlockedCompareExchange(&m_Flag,0,1);
}
public:
InterLock()
{
m_Flag = 0;
}
virtual ~InterLock()
{
}
};
200193:2009/11/05(木) 19:30:08
こっちはクリティカルセクション晩
class CriticalSection
{
private:
CRITICAL_SECTION cs;
public:
void Enter()
{
EnterCriticalSection(&cs);
}
void Leave()
{
LeaveCriticalSection(&cs);
}
public:
CriticalSection()
{
InitializeCriticalSection(&cs);
}
virtual ~CriticalSection()
{
DeleteCriticalSection(&cs);
}
};
201193:2009/11/05(木) 19:43:57
//グローバル変数
ロッククラス g_Lock;
int g_i = 0;

// 三つのスレッドで以下を走らせる
void Run()
{
for(int i=0; i<10000000; i++)
{
g_Lock.Enter();
g_i++;
g_Lock.Leave();
}
}

int main()
{
//3つのスレッドでRun()を走らせ、スレッド終了まで待機
(...省略)
cout << g_i << endl;
cout << time.result() << endl;
return 0;
}

結果
クリティカルセクション 35秒 g_i = 30000000
インターロック 5.5秒 g_i = 30000000
ロッククラス無し 0.16秒 g_i = 21203536(整合性無し)

環境 OS:win xp CPU:core2duo1.8G メモリ:3G
202デフォルトの名無しさん:2009/11/05(木) 20:42:07
ソースまともに見てないけど、CSがもしインライン化されないなら性能的には勝てない
だろうしなぁ
まぁ、asm読めば全て分かるだろうけど
203 ◆0uxK91AxII :2009/11/05(木) 23:23:50
TryEnterCriticalSection ~ Sleepだとどうなるの、っと。
threadをCPUと1:1にbindしたらどうなるの、っと。
timesliceを変えたらどうなるの、っと。

結果は書かない方が良い。
204193:2009/11/06(金) 07:01:38
>TryEnterCriticalSection ~ Sleepだとどうなるの、っと。
これだけやってみた。
上記のテストだとインターロックとの差は0.5秒内、
つまりほとんど差がなくなった
205デフォルトの名無しさん:2009/11/06(金) 13:00:12
プロセッサ数が2以上ならSpinWaitにしたらどうなる?
あとインターロックのIncrementでダイレクトアップデートにしたらどうなる?
206 ◆0uxK91AxII :2009/11/06(金) 20:26:47
違うネタだけど。
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#define THREADS 64
#define LOOPS 123456789
struct SData { LARGE_INTEGER m_cntBegin; LARGE_INTEGER m_cntEnd;};
DWORD WINAPI thread(LPVOID pArg);
int __cdecl cmpForSort(const void *pArg0, const void *pArg1);
int _tmain()
{
int i; HANDLE ahThread[THREADS]; SData aData[THREADS];
LARGE_INTEGER diff;
for (i=0; i<THREADS; i++)
ahThread[i] = CreateThread(NULL, 0, thread, &aData[i], 0, NULL);
WaitForMultipleObjects(THREADS, ahThread, TRUE, INFINITE);
qsort(aData, THREADS, sizeof SData, cmpForSort);
for (i=0; i<THREADS; i++)
{
CloseHandle(ahThread[i]);
diff.QuadPart = 0<i? aData[i].m_cntBegin.QuadPart - aData[i-1].m_cntBegin.QuadPart: 0;
_tprintf(_T("thread: %d, diffBegin: %I64d, clock: %I64d\n"), i, diff.QuadPart, aData[i].m_cntEnd.QuadPart-aData[i].m_cntBegin.QuadPart);
}
return 0;
}
207 ◆0uxK91AxII :2009/11/06(金) 20:28:49
DWORD WINAPI thread(LPVOID pArg)
{
SData *pData; DWORD value; float sum;
pData = (SData *)pArg;
QueryPerformanceCounter(&pData->m_cntBegin);
__asm
{
mov ecx, LOOPS
fldz
LOOP_:
fadd QWORD PTR value
dec ecx
jnz LOOP_
fstp DWORD PTR sum
}
QueryPerformanceCounter(&pData->m_cntEnd);
return 0;
}
int __cdecl cmpForSort(const void *pArg0, const void *pArg1)
{
LARGE_INTEGER diff;
diff.QuadPart = ((SData *)pArg0)->m_cntBegin.QuadPart - ((SData *)pArg1)->m_cntBegin.QuadPart;
if (0 > diff.QuadPart) return -1;
if (0 < diff.QuadPart) return 1;
return 0;
}
208 ◆0uxK91AxII :2009/11/06(金) 20:37:44
同じ処理なのに所要時間がブレるとか、
先に開始したthreadよりも、後から開始した方が早く処理を終えるとか。
そういうのが起こりうる。

computer gameでmulti threadの利用に消極的な理由の一つだと思う。
209193:2009/11/06(金) 23:12:33
>>205
>インターロックのIncrementでダイレクトアップデートにしたらどうなる?
1.3秒だった

>SpinWait
これC#じゃん
210デフォルトの名無しさん:2009/11/07(土) 01:40:37
スピン待機はC#限定じゃなく一般的な概念だ
211デフォルトの名無しさん:2009/11/07(土) 09:40:03
スピンすると余計遅くなりそうだな。
一般的な使用状況に比べて処理と競合がタイトすぎるせいかな多分。
212デフォルトの名無しさん:2009/11/07(土) 09:45:49
ああつまり3スレッド同時じゃなくて1スレッドで3回繰り返した方が速いとかっていう状態ね。
213デフォルトの名無しさん:2009/11/07(土) 17:33:40
あーいやいや、これだとちょっと書き方がおかしいな…まあいいや
214193:2009/11/07(土) 19:49:07
スピンロックは信頼性がないという話を聞いたような。

さて上記のベンチですが、1スレッドで3回繰り返したほうがずっと早いです。
衝突したときに別の処理をせずに待つ場合はシングルスレッドにした方がいいかも。
215デフォルトの名無しさん:2009/11/07(土) 20:02:47
スピンロックに信頼性が無かったらどうすんだよw
全然仕組みとか分かってなくて使ってる匂いがぷんぷんするな
216デフォルトの名無しさん:2009/11/07(土) 20:03:53
スピンロックとスピンウェイトは基本的に別物です。
217デフォルトの名無しさん:2009/11/08(日) 00:12:02
それと信頼性に何の関係が?
218デフォルトの名無しさん:2009/11/08(日) 02:55:49
スピン待ちの話をされてスピンロックどうこうと返すのがおかしい
219デフォルトの名無しさん:2009/11/08(日) 10:06:21
上の人じゃないけど、スピンロックはスピンウエイトを使ってやってるかとおもてたよ(´・ω・`)
220 ◆0uxK91AxII :2009/11/08(日) 12:45:22
spinlockでlockできる保証は無いね。
偶然上手く動いているだけ。
221デフォルトの名無しさん:2009/11/09(月) 01:48:53
◆0uxK91AxIIで検索したら、NGしてもいいくらいトンチンカンな奴だな
222デフォルトの名無しさん:2009/11/10(火) 14:27:27
トリップ付けるような奴だもの。
223デフォルトの名無しさん:2009/11/10(火) 20:06:21
トンチンカンなんて久々に見た
おやつあげないわよ
224デフォルトの名無しさん:2009/11/11(水) 09:14:41
抜作先生の方がまだ新しいな。
225デフォルトの名無しさん:2009/12/15(火) 00:01:41
マルチスレッド対応の基数木のアルゴリズムって
どうやって記述すればいいのでしょうか?

CかC++で探しています。
226デフォルトの名無しさん:2009/12/22(火) 22:31:16
読み込みと書き込みが1スレッドずつの場合でもメモリ破壊って起きるのでしょうか?

たとえば、ある変数をメインスレッドで読み込み続け、
複数のサブスレッドで、クリティカルセクションを用い、書き込むといった場合です
227デフォルトの名無しさん:2009/12/22(火) 22:39:31
>>226
とりあえず破壊読み出しメモリだと死ぬよね。
228デフォルトの名無しさん:2009/12/22(火) 23:29:29
>>226
まずメモリ破壊を定義してもらおうか
229デフォルトの名無しさん:2009/12/23(水) 01:41:11
パソコンのネジ外して開けると見えてくるメモリの部分をハンマーで叩く
230デフォルトの名無しさん:2009/12/23(水) 01:42:27
ハードウェア的な話題もするんか
231デフォルトの名無しさん:2009/12/23(水) 02:21:03
宇宙線による確率的なビット反転は防ぎようがない
232226:2009/12/23(水) 10:10:00
データが飛ぶという意味でのメモリ破壊です
ハード的にどのように動作しているのか分からないのですが
同アドレスに同時にアクセスされることによってメモリ破壊が起きるのでしょうか?
233デフォルトの名無しさん:2009/12/23(水) 10:20:05
書き込みをクリティカルセクションで同期して、クリティカルセクションを抜けたところで可視性が保証されたとしても、
読む方が書き込み中にその変数を見る可能性があるなら、少なくとも意図しない値を読む可能性はあるんじゃない?
(+不変な変数見てると思われるかもね)

要求次第だけど、
この手のポーリングするやつは、次に読めればいいからその瞬間のスナップショットで十分だと思うので、
Atomicな操作用のAPI使うとか、書き込みがAtomicであることが保証されるならvolatileだけでもいいかも。

その変数の読み書きだけ同期とっても、読んでる間の書き込みは防げても、
読み込みが終わってクリティカルセクション抜けたあと、それで処理しようと思ったら
もう書き換わってることもあるし。
読んだ値の処理が終わるまで書き込ませないなら、話は別だけど。
234デフォルトの名無しさん:2009/12/23(水) 11:15:37
昔使ったタイマ LSI でラッチ→lo-read→hi-readって
いう約束ごとのあるやつがあったな。hi-readでラッチ
が外れる奴。word-read 命令が使えるかどうかは CPU
次第。
235デフォルトの名無しさん:2009/12/23(水) 12:47:17
>>226
ハードや操作による。
つーか、まずは「アトミックな操作」という概念をどっかで調べとけ。

例えば、x86のCPUなんかだと、どういう操作がアトミックかはIntelが規定している。
アトミックな書き込みなら、別のコアからの読み込みが割り込む可能性は無い。逆に
アトミックでない書き込みなら、例えば半分くらい書き込んだところで別のコアが
読み込む可能性があるということ。
x86なら、厳密な規定はIntelの英語版サイトに落ちてる。32bitアラインドなreadや
writeは確実にアトミックだ。相当古いx86以外はキャッシュアラインドなら大丈夫。
read-modify-writeはLOCKプリフィクスが無い限りアトミックではないが、xchg
命令はLOCK#が自動的にアサートされるのでアトミックだ。
まぁ、アセンブラを直接叩くんじゃなければ、イントリンシック命令を調べておけば
十分だが、その裏でどういうCPUの動きをしているかは理解しといた方がいい。

つーか、低水準の話と高水準の話で全然違いすぎるんだよな。俺はどっちの話でも
構わんけど、分けた方がいいのか?
236226:2009/12/23(水) 12:53:08
ありがとうございます
もっと勉強します
237デフォルトの名無しさん:2009/12/23(水) 13:31:19
>>232
そんな事は起きないようにハードウェアが作られてる
物理的なメモリへのアクセス経路は1個しかないから、同じアドレスに同時にアクセス
なんて事は出来ない

命令が書いた順に実行されるかとか、他のコアやスレッド云々は >>235 の通り
238デフォルトの名無しさん:2009/12/23(水) 13:31:47
クリティカルセクションを用いって書いてあるから、なんとなくWindowsかと思ってた。
239デフォルトの名無しさん:2009/12/23(水) 13:32:15
>>235
ここはム板だから低水準の話はついていけないと思う
240デフォルトの名無しさん:2009/12/23(水) 13:49:38
>>237
> 物理的なメモリへのアクセス経路は1個しかないから、同じアドレスに同時にアクセス
> なんて事は出来ない

いつの時代の人?
241デフォルトの名無しさん:2009/12/23(水) 14:00:02
>>239
いやそれは無い
242デフォルトの名無しさん:2009/12/23(水) 14:00:28
ん?今はどこが違うの?
243デフォルトの名無しさん:2009/12/23(水) 14:04:04
>>235
x86は巨視的には古典的設計だからまだ理解しやすいけど、PPCなんかだとリオーダー
とかが剥き出しになってくるからさらにごちゃごちゃするんだよな
244デフォルトの名無しさん:2009/12/23(水) 14:06:45
そこでeioioですよ!
245デフォルトの名無しさん:2009/12/23(水) 14:07:20
間違えた、eieioだった
イーアイイーアイオー!
246デフォルトの名無しさん:2009/12/23(水) 14:28:55
エイッエイッオッー
247デフォルトの名無しさん:2009/12/26(土) 12:32:01
この辺の話題が体系的に書かれてる教科書が欲しい
248デフォルトの名無しさん:2009/12/26(土) 14:41:39
開拓が進行中のジャンルだから、書いたそばから陳腐化しそうでなかなか難しいかも
しれないな
249デフォルトの名無しさん:2009/12/31(木) 15:09:39
何をもって高性能とするかをはっきりさせたいな
シングルコア100%アイドル3コアでできることを4コア25%ずつで処理することに意味はあるの?
250デフォルトの名無しさん:2009/12/31(木) 15:12:36
>>249
に追記
並列処理の有利はわかるけど、これからは直列処理も並列化しようとしてるんでしょ
そんなの意味ないよねという話
251デフォルトの名無しさん:2009/12/31(木) 15:50:00
1コア100%3コア0%ってCPUがボトルネックになってんじゃねーの
252デフォルトの名無しさん:2009/12/31(木) 15:50:26
何を言ってるの?
253デフォルトの名無しさん:2009/12/31(木) 21:19:08
>>249は軽くエスパーが日本語に翻訳しないと分かりづらい

4スレッドにしたら全部25%になっちゃうような処理までマルチスレッドにする
意味あんの、って言いたいんだろうし、だからCPU屋は2コアや4コアで現状維持
しながら別の進化の方向性を探ってるのも事実
だがそもそも、そういう微妙なケースにまで頑張って適用しようぜMTマンセー、
というようなスレではないので、そんな的外れなこと言われても一瞬何の話だか
分からんし、今更何をとしか言いようがない
254デフォルトの名無しさん:2009/12/31(木) 21:28:43
>>253
日本語でおk
255デフォルトの名無しさん:2009/12/31(木) 21:35:30
>>253
余ってるCPUに仕事振る余地のない処理なら
それでいいんじゃね?
256デフォルトの名無しさん:2009/12/31(木) 21:39:14
>>249の問題提起自体が微妙
アムダールの法則くらいで十分じゃねーの?
257デフォルトの名無しさん:2010/01/03(日) 18:49:32
そもそも並列化できない処理まで並列化しようとしてるなんて話は聞いたこともない。
誰が言ったんだそんなこと。
258デフォルトの名無しさん:2010/01/03(日) 21:49:55
>>249が言ってるな
259デフォルトの名無しさん:2010/01/16(土) 03:00:47
質問させてください。
【OS】 UNIX/LINUX
【言語】 C言語
【実行環境】 gcc
【その他特記する事項】
メインスレッドからn個のスレッドを作成->全ての終了を待つという場合、
int i;
pthread_t id[n];
void* res[n];
for (i=0; i<n; i++)  pthread_create(&id[i], NULL, funcptr, arg);
for (i=0; i<n; i++)  pthread_join(id[i], &res[i]);
こんな感じで大丈夫でしょうか?
それとWindowsにあるWaitFor〜みたいに複数待つというのは無いのでしょうか?
260デフォルトの名無しさん:2010/01/16(土) 03:18:30
>>259
>WindowsにあるWaitFor〜みたいに複数待つ

http://developers.sun.com/solaris/articles/event_completion.html
261デフォルトの名無しさん:2010/01/26(火) 00:12:16
スレッドを終了させないままアプリを閉じた場合
やっぱメモリリークとか起きるの?
262デフォルトの名無しさん:2010/01/26(火) 00:20:29
環境を想定しないとなんともいえない。
263デフォルトの名無しさん:2010/01/26(火) 00:33:22
>>261
OS破壊されるぞ?いいのかそんなことしても
264デフォルトの名無しさん:2010/01/26(火) 00:49:27
>>261
ja.wikipedia.org/wiki/メモリリーク
265デフォルトの名無しさん:2010/01/26(火) 10:22:10
破壊されるようなOSなんか使うなw
266デフォルトの名無しさん:2010/01/26(火) 16:03:33
MTでそんな脆いOSはちょっと想像付かないなw
携帯の奴とかはどうなんだろう
267デフォルトの名無しさん:2010/01/26(火) 16:15:09
問題(1) 名前を入れる入力ダイアログ1つとボタンを1つ表示し,ボタンを押したときは時間に応じて,
 05時〜11時 「おはようございます,○○さん」
 11時〜17時 「こんにちは,○○さん」
 17時〜05時 「こんばんは,○○さん」
と表示するJavaScriptプログラムを作成しなさい。
268デフォルトの名無しさん:2010/01/26(火) 16:20:40
断る。
269デフォルトの名無しさん:2010/01/26(火) 16:24:21
キミの実力を見せてみろ
270デフォルトの名無しさん:2010/01/26(火) 16:28:23
マルチスレッドと何の関係が
271デフォルトの名無しさん:2010/01/26(火) 16:32:31
スレ違いでした。
すいません・・
272デフォルトの名無しさん:2010/01/26(火) 17:10:35
VCでマルチスレッドアプリをトレース実行してるとかなりの頻度でOSごと固まるんですが、
マルチスレッドの場合のデバッグはデバッガ使わないのが普通なんですか?
273デフォルトの名無しさん:2010/01/26(火) 17:48:30
PCが貧弱
274デフォルトの名無しさん:2010/01/26(火) 18:05:06
嫁が貧乳
275デフォルトの名無しさん:2010/01/26(火) 18:13:39
ユーザが頻尿
276デフォルトの名無しさん:2010/01/26(火) 18:19:25
>>272
詳細なテキストサービスをオフにすると少し幸せになれるかも。
ATOK使いの俺には無縁な話。
277デフォルトの名無しさん:2010/02/02(火) 23:21:31
最近スレッド使い始めました。
クリティカルセクションとかインターロックで変数を共有するのは
なんとなく分かりました。
例えばCRITICAL_SECTIONを使う場合、アプリケーションで一つ用意すれば
よいのでしょうか?
極端に言えばCRITICAL_SECTIONをグローバル変数として定義して、
EnterCriticalSection等を使えばよろしいのでしょうか?
278デフォルトの名無しさん:2010/02/02(火) 23:33:23
トイレに例えるなら何個個室があっても鍵がすべて連動してトイレにはひとりしか入れないってことだぞ
それでいいのか?
279デフォルトの名無しさん:2010/02/02(火) 23:44:28
それでも良いが性能は良くない
性能向上のためにスレッドを使っているわけではないのなら、別に構わない
無理にシングルスレッドで処理するよりマルチスレッドの方が可読性が高くなることもあるからな
性能を上げたいのなら一人がどこかでロックを握ってる間全員が待たされるような構造は良くない
280277:2010/02/03(水) 00:18:41
なるほど。問題点の指摘ありがとうございます。
では、3つスレッドがあるとして、1つは無関係で2つのスレッドで
変数を共有する場合は、クリティカルセクションをどう使えば
よろしいのでしょうか?
各スレッドループ中にCRITICAL_SECTIONを定義してりようすればよろしいのでしょうか?
何か根本的に勘違いしている気がしている気がします。
281デフォルトの名無しさん:2010/02/03(水) 00:32:42
共有する変数がグローバルで1個しかないのならクリティカルセクションもグローバルで1個でいいよ
282277:2010/02/03(水) 00:50:34
現在は全体からアクセスできる変数が一つです。
一気にやろうとはしないで少しずつ複雑なパターンを試してみます。
あと環境はWindowsです。失礼しました。
283デフォルトの名無しさん:2010/02/03(水) 01:35:14
まあロックが1つで済むならデッドロックとか考えなくて済むし
可能ならその方が悩まない。
パフォーマンスの問題は、占有期間次第とも言えるから。
284デフォルトの名無しさん:2010/02/03(水) 02:19:04
クリティカルな部分一個をトイレの個室一つと考える
285デフォルトの名無しさん:2010/02/03(水) 04:12:03
たまに鍵かけないやつがいてトラブるんだ
286デフォルトの名無しさん:2010/02/03(水) 07:23:37
そうするとトイレの中に
トイレがあって、その中にまたトイレがないと
説明不可能だろ。

トイレはネストできねーだろ
287デフォルトの名無しさん:2010/02/03(水) 09:11:21
そうかクリティカルセクションはネスト出来たか
288デフォルトの名無しさん:2010/02/03(水) 11:33:20
じゃあトイレがバスルームにあるということで
289デフォルトの名無しさん:2010/02/03(水) 11:42:57
階層数に制限があるからダメ。
290デフォルトの名無しさん:2010/02/03(水) 11:52:56
トイレ中に地震がくるのと
小便中に大便を催すのと
どっちが我慢できる?
291デフォルトの名無しさん:2010/02/03(水) 13:45:14
メモリバリアとmutexの関係が解りません。
メモリバリアとmutexがどういうものか。とかじゃなくて、
関係性とか、必要とされる場面について解説してあるサイトないですか?
292デフォルトの名無しさん:2010/02/03(水) 13:59:08
メモリバリア
http://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%A2%E3%83%AA%E3%83%90%E3%83%AA%E3%82%A2

メモリバリアは単に自CPUのメモリアクセスの順序を制御するだけのもので、
mutexのようなスレッド間の排他制御 (後続のスレッドを進入させずに待たせるような) 機能は無い
メモリバリアはCPUの1命令に過ぎず、mutexはOSのスレッド管理と絡むもっと複雑なものだ
mutexを実装するOSの中の人は、複数のCPU間の連携のためにメモリバリアを使うかもしれない
293デフォルトの名無しさん:2010/02/03(水) 16:33:38
メモリバリアかアトミック命令が無いとMutexは実装出来ない
294デフォルトの名無しさん:2010/02/03(水) 20:55:32
>>291 は同期処理のバリアのことじゃないの?
http://ja.wikipedia.org/wiki/%E3%83%90%E3%83%AA%E3%82%A2_%28%E8%A8%88%E7%AE%97%E6%A9%9F%E7%A7%91%E5%AD%A6%29

ロードストアのオーダリングの話と mutex はちょっと離れてる気がする
295デフォルトの名無しさん:2010/02/04(木) 17:45:59
>>286
クリティカルセクションのネストって必要かな?
296デフォルトの名無しさん:2010/02/04(木) 17:49:29
クラスのスレッドセーフなメソッドから同クラスのスレッドセーフなメソッドを呼び出す場合とかにあると便利かも

そういう動作を意図しなかった場合にバグらないっていう利点もあるね
297デフォルトの名無しさん:2010/02/04(木) 17:55:39
同クラスなら同期処理しないプライベートメソッドを呼び出すのではないか
298デフォルトの名無しさん:2010/02/04(木) 19:04:48
たとえば口座aから口座bに振替をおこなうには、
口座aと口座b両方のロックを取る必要がある、
という典型的な例は?
299デフォルトの名無しさん:2010/02/05(金) 08:24:35
それは二つのCSをロックするだけでネストじゃないんでね?
300デフォルトの名無しさん:2010/02/05(金) 09:08:04
こんな話題とメモリバリアの話題が同時進行するってかなりカオスな気がする
301デフォルトの名無しさん:2010/02/05(金) 13:10:17
>>298
同時に入ってる必要は無くね?
302デフォルトの名無しさん:2010/02/05(金) 21:40:05

両方とも、a→bの流れならトランザクションだけでよくないか?
303デフォルトの名無しさん:2010/02/06(土) 00:40:47
スレッドがA、B、C、Dの4つあって
かならずA、B、C、Dの順番で仕事が
終わるようにするには

どんなアルゴリズム使えばいいのですか?
304デフォルトの名無しさん:2010/02/06(土) 00:46:46
スレッド化する意味あるのか?
B,C,Dは寝かせておいて、Aが自分の仕事を終えたときにBを起こせばいいんじゃないか
305デフォルトの名無しさん:2010/02/06(土) 13:44:25
スレッドの終了処理を順番にやる必要があるってことかな。
終わるタイミングを調整したいだけなら、
BがAの終了を待つ
CがBの終了を待つ
DがCの終了を待つ
って感じにやれば順番に終われるんじゃね?
306デフォルトの名無しさん:2010/02/06(土) 18:28:33
そしてAがDの終了を待てば完璧
307デフォルトの名無しさん:2010/02/06(土) 19:34:45
>>306
どうやって全部待てばいいの?
308デフォルトの名無しさん:2010/02/06(土) 20:36:58
Eに管理してもらう
309デフォルトの名無しさん:2010/02/06(土) 20:51:33
どうやるのか全然わからない

たすけて
310デフォルトの名無しさん:2010/02/06(土) 22:14:37
Aの処理終了の際に2個のスレッドで破れるBarrier1を待つ
Bの処理開始の際に2個のスレッドに破れるBarrier1を待つ
Bの処理終了の際に2個のスレッドに破れるBarrier2を待つ
Cの処理開始の際に2個のスレッドに破れるBarrier2を待つ
Cの処理終了の際に2個のスレッドに破れるBarrier3を待つ
Dの処理開始の際に2個のスレッドに破れるBarrier3を待つ
311デフォルトの名無しさん:2010/02/06(土) 22:16:11
>>310
>スレッドで破れるBarrier
こんなことすると破綻すると思うのですが
それは何か新しい概念なのでしょうか?
312デフォルトの名無しさん:2010/02/06(土) 22:46:53
>>311
>>294のバリアのことだよ。
2個のスレッドがバリアに到達した瞬間にバリアが破れて同時に進行を再開する。

Wikipediaより…
並列コンピューティングにおけるバリア(英: Barrier)とは、同期方法の一つであり、
ソースコード中でスレッドやプロセスがある箇所で停止し、
他の全てのスレッドプロセスがバリアに到達するまで進行しないようなものを示す。
313デフォルトの名無しさん:2010/02/07(日) 00:29:35
>>310
わかりにくい表現だな。
314デフォルトの名無しさん:2010/02/07(日) 21:28:39
同期なり待機って言った方がわかりやすいな
315デフォルトの名無しさん:2010/02/11(木) 00:13:07
追加削除順序を保持しつつ
効率的にアクセス可能なデータ構造って何があるの?
316デフォルトの名無しさん:2010/02/11(木) 00:25:04
二分木
317デフォルトの名無しさん:2010/02/11(木) 00:32:33
>>316
マルチスレッドの2分木のサンプル
教えて
318デフォルトの名無しさん:2010/02/11(木) 00:50:06
>>315
Skip list.
実装例は java.util.concurrent.ConcurrentSkipListSet とかかな。
319デフォルトの名無しさん:2010/02/20(土) 11:14:34
C++のマルチスレッドの本って
どんなのがありますか?

Intelの本は使い方しか書いてないで
困ってる
320デフォルトの名無しさん:2010/02/20(土) 12:39:32
正直、使い方だけしか提示しようがない気がする
どこもかしこも開拓中で、定番というものが無い
321デフォルトの名無しさん:2010/02/21(日) 18:06:11
>>319
Java並行処理プログラミングマジオススメ。
直接同じことは出来なくても、考え方は大いに参考になる。
volatileだけはC++と全くの別物なので注意だけど。

boost.threadのfutureでJavaのExecutorフレームワークに近いことが出来そうだなぁ。
322デフォルトの名無しさん:2010/02/21(日) 18:16:04
>>321
その程度の書籍薦められても困るんだよ
もっとまともな本持って来い
323デフォルトの名無しさん:2010/02/21(日) 18:29:39
>>322
Java並行処理プログラミングでも満足できない貴方には
↓がお勧め。
http://scholar.google.com/
最先端の研究成果が大量に手に入るぞ。
324デフォルトの名無しさん:2010/02/21(日) 19:01:28
>>322
もっとまともな本があるなら俺も知りたいけどね。
325デフォルトの名無しさん:2010/02/21(日) 23:35:25
並行コンピューティング技法――実践マルチコア/マルチスレッドプログラミング
ttp://www.oreilly.co.jp/books/9784873114354/
326デフォルトの名無しさん:2010/02/22(月) 16:37:56
begintreadexを使ったときはclosehandleを使わないといけないらしいけど
CloseHandle((HANDLE)_beginthreadex());
こんな感じでいいの?
327デフォルトの名無しさん:2010/02/22(月) 16:42:48
beginthreadexが返したハンドルを渡すのかと聞いているのならYES
328デフォルトの名無しさん:2010/02/22(月) 17:44:29
_beginthreadexはなんで整数型で返すんだろう
329デフォルトの名無しさん:2010/02/22(月) 22:11:07
Win32の型を持ち込みたくなかったからじゃないの。
330デフォルトの名無しさん:2010/02/23(火) 00:27:00
意味も無く汚くはしないしな、いくらMSでも
331デフォルトの名無しさん:2010/02/23(火) 00:29:08
void *じゃだめなのか
332デフォルトの名無しさん:2010/02/23(火) 08:52:12
それだと32bitであることを強調できないからやめたんじゃないかな
333デフォルトの名無しさん:2010/02/23(火) 14:32:40
一応今はuintptr_tだしな
まぁ毎度のレガシーの枷なんだろうし、仕方ないっつーか正直どうでもいい
334デフォルトの名無しさん:2010/03/07(日) 15:36:02
どちらかというとマルチコア絡みの質問ですが
テンプレにある該当スレは過疎ってるぽいのでこちらで質問させていただきます

Q1. Windowsはスレッドコンテキスト切替時、汎用レジスタ同様にxmmレジスタを待避/復帰しますか?
   主にWindows 7 (32 bit)とWindows 7(64 bit)について知りたいですが、他のも回答いただけると有難いです

Q2. そもそもCore i7のSIMDモジュールってコア毎に独立してますか?
   独立してるっぽいけど、確証となるブロックダイアグラムみたいなのがIntelのドキュメントを漁っても見つからないorz

Q3. Core i7の分岐予測メモリって、コードが共通なら全スレッドで共通?それともスレッドコンテキスト毎にきちんと別統計になるんでしょうか?

Q4. VC(2008)付属ライブラリの数学関数(おそらくコプロセッサを使うはず)はスレッドセーフですか?またそれは/fp:オプションによらず不変?

よろすくおながいしますorz
335デフォルトの名無しさん:2010/03/07(日) 16:24:51
A1: Windows 98, 2000以降はyes
A4: yes
336デフォルトの名無しさん:2010/03/07(日) 16:51:28
A2 コア別でしょう。たぶん。コア間共有なんて設計のほうが難しいと思うよ。
A3 コア別でしょう。たぶん。コア間共有なんて設計のほうが難しいと思うよ。
337デフォルトの名無しさん:2010/03/07(日) 17:32:40
>>326
>CloseHandle((HANDLE)_beginthreadex());
その組み合わせはちょっちまずくね?
ttp://msdn.microsoft.com/ja-jp/library/cc429080.aspx
にメモリリークが起きると書いてある(ちなみにやねうら本(1)にもそう書いてある)
ExitThread()を明示的に呼ばなくても、スレッド関数を抜けたら同じことのはず

なお、>326の反対(CreateThread()が返したハンドルを _endthread()で開放する)は明白に危険であろうことが上のリンク先から推測できる
(確保されていないメモリを_endthread()が解放しようとするハズ)
338デフォルトの名無しさん:2010/03/07(日) 18:07:36
何のために_beginthread()〜_endthread()や_beginthreadex()〜_endthreadex()があるかというと
strtol()みたいに、機能的にはマルチスレッド環境下でも動いて欲しいのだが関数仕様的にマルチスレッドと相容れないような
標準関数をマルチスレッド環境でもきちんと動くようにする目的なので(おそらくそのために内部的にスレッド局所記憶を確保している)
そういう類の関数を明示的にも暗黙的にも呼び出さないと誓うならCreateThread()〜CloseHandle()で無問題
339308:2010/03/07(日) 18:19:56
スマソstortol()じゃなくて問題なのはstrtok()とかlocaltime()とかだった、
340デフォルトの名無しさん:2010/03/07(日) 18:53:55
>>337
_beginthread は起動されたスレッドが終了時にハンドルのクローズを行う。
_beginthreadex は別途CloseHandleする必要がある。その代わり、
スレッドが終了していてもハンドルは有効であり、スレッドの状態を調べることができる。
ここでのリークというのはCRTの作業域のことではなくて
あくまでもスレッドを追跡するためのハンドルのこと。
341デフォルトの名無しさん:2010/03/07(日) 22:27:39
>335, >336
レスdクス
A1は実験的にも確認できた(イントリンシック関数が排他を含まないこと、およびxmm0とxmm1を使う関数を64スレッドで呼び出して無問題)
A2はまあそう思う(ダイ写真でSIMDとコアの区別を確認できない&SIMDの数<コアの数ではマルチメディア目的に合致しない)
A4についても使用予定関数について実験的に確認できた

A3はちょっち謎
同一コードで記述され、同一コアで走る別スレッド(含HT)の場合どうなるのか?
同一コード条件とそうでない条件(コードをスレッド別コピーとする)とで速度比較すればいいんだろうけども
コードをコピーすると分岐予測以前にトレースキャッシュ容量他の要因で速度低下するかもしれないから実験では精度良くは判断できない鴨
342デフォルトの名無しさん:2010/03/08(月) 00:36:48
pthread_cond_wait状態になるまでに
結構時間かかるのですかね?

以下のようなコードを実効すると
結構頻繁に、別のスレッドがwait状態になる前に
pthread_cond_signalを実効してしまうのですが
必ず、同期取るようにどうしたらいいのでしょうか

thread1
{
while(1){
pthread_mutex_lock(&m);
pthread_cond_wait(&c, &m);
pthread_mutex_unlock(&m);
}

}

main
{
while(1) {
pthread_mutex_lock(&m);
pthread_cond_signal(&c, &m);
pthread_mutex_unlock(&m);
}
}
343デフォルトの名無しさん:2010/03/08(月) 00:39:08
どうやって確認したの?
344デフォルトの名無しさん:2010/03/08(月) 00:45:01
何がしたいのかよくわからんが、
とりあえずmutex取得する前にシグナル発行してたらいかんだろう。
345デフォルトの名無しさん:2010/03/08(月) 00:54:13
thread1がlockするまえにmainがlock->signalしちゃってるとかありそう
346デフォルトの名無しさん:2010/03/09(火) 07:06:51
>>337-338
つーか比較するものが間違ってる
_endthread()/_endthreadex()は作られた側が(必要なら)呼び出すもので
CloseHandleは_beginthread()/_beginthreadex()呼んだ側が呼び出すもの
347341:2010/03/13(土) 23:42:54
自己解決しますた!(いや、多分、だけど

Windowsのスレッドコンテキスト切替は、スレッドが走り続けている場合、どうがんばっても
msオーダー周期(おそらく10 msとか20 msに1回)なので、分岐予測統計の結果がその間に十分安定する(と思われ

だから分岐予測精度を上げるためにコードのコピーをスレッド別に用意しておく、みたいな神経質なことはしなくて宜しい

かと、
348342:2010/03/14(日) 01:04:34
訂正
 誤:分岐予測統計の結果がその間に十分安定する(と思われ
 正:分岐予測統計の結果が現実的に安定している期間よりも桁違いに長い(と思われ

ニホンゴ、ムズカシイデス、、
349デフォルトの名無しさん:2010/03/14(日) 02:03:43
いやいやいやいや
いまはコア間での話ではなかったのか?
350デフォルトの名無しさん:2010/03/14(日) 08:00:00
またえらい細かいオーダーで削ってるんだなぁ。
PCのWindowsでそこまでカツカツ削っても、すぐに時代変わっちゃうと思うけどなぁ。
他のとこに力入れた方が良くね?
まぁ、トレースキャッシュとか気にしてるから、何か特殊な固定環境向けのガリガリな
チューニングなのかもしれないけど。
俺も低レベルは好きだから、とりあえず触ることで知識と感覚を深めたい、ってんなら
止めないけど。単にバランス感覚の欠けてるケースに見えてしまうが。違ったらすまん。
351デフォルトの名無しさん:2010/03/14(日) 08:19:21
>>349
分岐予測メモリはCore i7の場合物理コアごとに持ってるからスレッドごとに物理コアを違える場合は何も悩む必要はない
問題なのはスレッドの数が物理コア数より多いとか、同一物理コア内でのHTの場合(→341の下から3行目参照)
352デフォルトの名無しさん:2010/03/14(日) 08:30:59
ハッよく考えたら>348-349のロジックじゃあHTの場合が解決してねーじゃんorz
同一コア内で走るHT0とHT1は、ハードウェアレベルで演算ユニット、L1, L2キャッシュ、トレースメモリを奪い合うので
もし仮に分岐予測メモリのタグがアドレスのみから生成され、HT番号では区別されない作の場合問題になりえる

ただしまあ現実的には同じアドレスに配置された同じ条件分岐命令が
 1. HT0とHT1でほぼ同時に(=分岐予測結果の平均寿命(おそらく数μsec)オーダーの時間差内に)実行されるという状況が
 2. 片方は分岐、片方は非分岐で
 3. 無視し得ない頻度で反復される
というケースでのみ問題だが

>>350
というわけでWindows非依存な話
353デフォルトの名無しさん:2010/03/14(日) 08:32:37
>>352
いや本人がWindows7を対象にしてるって最初に言ってるから
354デフォルトの名無しさん:2010/03/22(月) 00:57:55
>>342
亀だが、それは条件変数の使い方を間違えとる
いきなり無条件でcond_waitで待ってはいかん
cond_waitは、あくまで「共有条件が望む状態になっていない時」に使うものだ
cond_wait時に指定するmutexは、その「共有条件」をテストするためのものだ

でもってcond_signalやcond_broadcastは、共有条件の変更があったことを通知して、共有条件の再テストの機会を与えるものだ
なお、cond_signal, cond_broadcastの実行そのものには、mutexの取得は必要ない

JMなんかのpthread_cond_initのmanページを見て、使用例を確認すると良い
355デフォルトの名無しさん:2010/03/27(土) 11:48:41
pthreadの記事を見つけたので読んでたら、
なんかコメントで色々指摘が入ってるんだけど、どうなの?
ttp://codezine.jp/article/detail/1894
356デフォルトの名無しさん:2010/03/27(土) 15:08:07
ここのコメント欄みづらいんだよね

最初の「必要以上に複雑になってる」という指摘は同意。
この記事って、バグのあるコードをだんだん直していくっていう
流れだけど、そもそもタイトルの条件変数関係ないバグだし、
修正内容も、なんか泥沼に入っていくような感じ

その後のやりとは、この二人にしか分からないどうでもいいことについて、
どうでもいいやりとりしてるように見えた。
357デフォルトの名無しさん:2010/03/27(土) 15:20:18
>>338
これはわかりやすい!
358デフォルトの名無しさん:2010/03/29(月) 23:05:41
「Java並行処理プログラミング」が増刷してる
359デフォルトの名無しさん:2010/04/18(日) 10:57:03
va_argsってスレッドセーフですか?
360デフォルトの名無しさん:2010/04/18(日) 21:21:11
va_list を自動変数やTLBに置いていれば、va_listをスレッド間で共有しない限りは、スレッドセーフだと思うぞ。
361デフォルトの名無しさん:2010/04/18(日) 22:11:15
>>360
嘘ついちゃだめ
va_listはプロセスで1つだけしか持てないから
スレッドセーフじゃないよ
362デフォルトの名無しさん:2010/04/19(月) 00:34:37
ボナンザ8コア対応を16コア対応にする方法を教えて下さい。
363デフォルトの名無しさん:2010/04/19(月) 06:51:44
スレッドセーフかどうかってのはcrtのソース見ないと判断付かないって認識でおkっすか?
364デフォルトの名無しさん:2010/04/19(月) 07:04:05
>>361
適当ぶっこくなカス
365デフォルトの名無しさん:2010/04/19(月) 07:18:38
>>364
じゃあ証明してくれよ
できないだろw?
366デフォルトの名無しさん:2010/04/19(月) 07:28:20
>va_listはプロセスで1つだけしか持てない
367デフォルトの名無しさん:2010/04/19(月) 07:59:36
それとスレッドセーフの話にどんな関係が?
368デフォルトの名無しさん:2010/04/19(月) 08:31:37
>>365
簡単。

va_listはプロセスで複数もてるから
スレッドセーフ
369デフォルトの名無しさん:2010/04/21(水) 11:18:50
すみません、spin-lockをしている間にCPUの使用率を下げる方法を知っている方はいますか?
調べてみると、rep;nop命令やSSEのpause命令をがそれに該当するように思えるのですが、
使ってみても何ら変わりませんでした。
自作のスレッドバリア関数(自作のspin_lock)を作って、
たとえば、
if(threadnum=5) sleep(10);
my_barirrer();

とするとスレッド5を待っている間は5以外のCPU使用率が100%近くなってしまいます。
それに対してOpenMP使った場合では、
if(threadnum=5) sleep(10);
#paragma omp barirrer

だと待っている間はCPU使用率は殆ど変わりません。
ちなみに自作のspinlockは下記のような感じです。
if(thread_num == 0)
{
asm volatile(
"Loop1:\n\t\t"
"movl (%0), %%eax\n\t\t"
"movl (%1), %%ebx\n\t\t"
"lfence\n\t\t"
"cmpl %%ebx, %%eax\n\t\t"
"rep;nop\n\t\t"
"jne Loop1\n\t\t"
:
:"r"(&lock->sync), "r"(&lock->maxthreads)
:"memory","%eax","%ebx"
);
370 ◆0uxK91AxII :2010/04/21(水) 15:37:33
>>369
方法はあるけど、物凄くマヌケで無意味だから誰もやらない。
371デフォルトの名無しさん:2010/04/21(水) 19:01:35
スレッドとかの切り替えを自前で用意するとか
372369:2010/04/22(木) 09:40:25
いろいろと試してみたのですが、マヌケな方法しか思いつきませんでした。
(スピンを何回かしたら、nanosleepを使うとか)
pthreadのライブラリのソースを見てみると、futexのシステムコールが呼ばれているようですね。
OpenMPで生成したスレッドの中で実行される関数間でスレッドの同期をとりたかったのと、
せっかくOpenMPを使っているから、
pthreadとか使いたくなかったので自前のspin_lockを作ってみました。
マヌケな質問をしてすみませんでした。

373デフォルトの名無しさん:2010/05/08(土) 03:22:14
ヒント:スピンロックを使わない
374デフォルトの名無しさん:2010/05/09(日) 22:01:03
Win32でスレッド間のイベント通知をやりたいんですが
2つのスレッドが同時にそれぞれSetEvent(), ResetEvent()を呼び出した場合の動作って定義されてるんでしょうか?
やっぱりクリティカルセクションで囲ってやらないとまずいですか?
375デフォルトの名無しさん:2010/05/09(日) 22:39:08
>>374
囲む必要は無い。
376デフォルトの名無しさん:2010/05/10(月) 08:17:54
>>375
ありがとうございます。
377デフォルトの名無しさん:2010/05/10(月) 20:41:23
イベントオブジェクト自体の動作には問題ないけど、
使い方ミスりやすいから十分気を付けた方がいいよ。
378デフォルトの名無しさん:2010/05/10(月) 23:08:00
プロのコードではイベントオブジェクトは使われない
379デフォルトの名無しさん:2010/05/10(月) 23:37:24
配布したときに問題が出るからな
380デフォルトの名無しさん:2010/05/11(火) 03:50:40
どんな?
381デフォルトの名無しさん:2010/05/12(水) 22:45:33
無名にすれば他のプロセスと衝突することも無いし、kernel32.dllだから別にDLLも不要だし問題が思いつかないな
382デフォルトの名無しさん:2010/05/13(木) 07:37:01
なんか勘違いしてんだろ
383デフォルトの名無しさん:2010/05/16(日) 21:15:32
wait-freeなキューの実装を可能にするのに必要な不可分操作ってどんなんですか?
384デフォルトの名無しさん:2010/05/16(日) 23:08:56
候補となる不可分操作には何があるの?
385383:2010/05/16(日) 23:57:41
>384
JAVAのConcurrentLinkedQueueだとCASをつかってるってことしか知りませんが..
386デフォルトの名無しさん:2010/05/18(火) 00:45:56
387デフォルトの名無しさん:2010/05/20(木) 23:12:58
スレッド間のヘルスチェックに定番な方法ってあるのでしょうか?
 ・マスターなスレッドAが外部変数にスレッド数分bit1を立てる
 ・B以降のスレッドは、自分に対応するbitを落とす
 ・一定時間、0じゃなかったら誰かが止まってるのでNG
とかすると、sem_wait()で普段寝ている人(これはその時だけ起こせばいい?)や、
recvやselectで待ってる人の確認はできない。。
388デフォルトの名無しさん:2010/05/21(金) 00:00:00
スレッドのヘルスチェックって要るのかな?プロセス間だったら必要かも知れなけど。
389デフォルトの名無しさん:2010/05/21(金) 00:05:09
大事な役割を持ったスレッドが刺さってないか確認したいんじゃないの
390デフォルトの名無しさん:2010/05/21(金) 01:47:25
タイムアウト指定して待ちっぱなしにならないようにするのが基本
391デフォルトの名無しさん:2010/05/21(金) 18:56:29
ワーカースレッドとUIスレッド分けたとき、時間のかかる作業を
ワーカースレッドがしているとき、UIスレッドはどうしているべきでしょうか

今は終わるのを待たずに終わるまでデータ変更の起こる操作を禁止しています
でもそれだとウィンドウ動かせるくらいしかメリットがないので考え中です
392デフォルトの名無しさん:2010/05/21(金) 19:03:15
>>391
俺は[中止]ボタンが押されるのを待つか、タイマーで定期的に終了したかどうか
チェックしてる。あとプログレスバー表示。
393デフォルトの名無しさん:2010/05/21(金) 19:49:50
ボタンを禁止にしたりキャンセルを受け付けたり面倒だよな
それとプログレって、量的な変化ならいいが、
手続き的な進行表示には不向きだよな
394デフォルトの名無しさん:2010/05/21(金) 20:05:26
全体量がわからないやつはつらいよね
\-/-\-...ってやつが好きw
395デフォルトの名無しさん:2010/05/21(金) 21:03:40
経過表示なら1/n「(説明)」〜n/n「完了」でいいと思うんだ
396デフォルトの名無しさん:2010/05/24(月) 23:34:30
progress_display「呼んだ?」
397デフォルトの名無しさん:2010/05/25(火) 09:11:50
いや、全然呼んでないよ
398デフォルトの名無しさん:2010/06/26(土) 14:48:12
マルチスレッド・アプリケーション開発のためのインテル・ガイド
http://www.xlsoft.com/jp/products/intel/article/guide/index.html
399デフォルトの名無しさん:2010/06/27(日) 14:54:02
>>391
おれはその処理に関連するメニューだけロック(選択不可とか無視とか)して他の操作は許可してる
処理が終わったら通知ポップアップ
処理状況なんかはモーダレスじゃないプログレスバーかステータスバー表示
400デフォルトの名無しさん:2010/06/27(日) 15:01:41
>>393
でも長時間うんともすんとも言わないと不安になるからそういう場合は一秒に一ブロックぐらい進むプログレスバー繰り返してる
中止は処理スレッドに定期的に中断フラグチェックさせてプログレスバーダイアログのOnClose/OnCancelで終了フラグOn+WaitForSingleObjectさせればOK
401デフォルトの名無しさん:2010/07/02(金) 23:09:47
ttp://blogs.wankuma.com/jitta/archive/2010/02/05/185818.aspx
なんかえらい絡まれてるくらい突っ込まれてるみたいなんだけど
やっぱりこの記事おかしいの?
それともコメントの方がおかしい?
402デフォルトの名無しさん:2010/07/02(金) 23:28:25
>>401
バブルソートを題材にするとか並列化のサンプルとして適切じゃないというかフェアじゃないというか、あえてそれを選ぶのはなぜ?って話でしょう。
403デフォルトの名無しさん:2010/07/02(金) 23:40:12
>何でもかんでも並列化すれば、等しく速くなるわけではない

記事の結論には同意だけど記事書いてるひとはアホ
404デフォルトの名無しさん:2010/07/03(土) 02:56:46
>>403
同意だな。
並列化に向いたアルゴリズムをつかわにゃ早くならんしな。
ていうか変数shareしすぎ。
405デフォルトの名無しさん:2010/07/03(土) 08:13:40
だらだらと下手糞なコードを書いて速くならねえよと喚かれてもな
そんな記事にはほとんど価値がない
406デフォルトの名無しさん:2010/07/03(土) 09:47:23
結局バグってたっぽいw
コメントが間違ってなければだが。
407デフォルトの名無しさん:2010/07/03(土) 10:07:39
記事自体は、アルゴリズムによって効率的に並列化できるとは限らないから云々んという内容なので、
記事自体が(素人にとっては)無意味だとまでは言わんが、
この人偉そうな言い方したり他人の記事に対しては重箱レベルで突っ込んだりもしてるくせに
自分の記事は内容が結構いい加減なんだよな。
408デフォルトの名無しさん:2010/07/03(土) 11:48:12
そんな人は世間にはいっぱいいる
409デフォルトの名無しさん:2010/07/03(土) 23:15:55
「並列処理は〜」と一般化された題材に対して、帰納法で証明しようとしているのが問題かな
「マルチスレッドに向かないアルゴリズムがある」というテーマならこの方法で十分だけど
410デフォルトの名無しさん:2010/07/04(日) 00:08:29
むしろ、そうじゃない人を見たら驚く。ライターなんてゲームの販売と同じ。
品物を売るまで、記事を読ませるまでが勝負。その後や内容なんて気にしなくてよい。
411デフォルトの名無しさん:2010/07/04(日) 00:24:14
ライターじゃないだろ
412デフォルトの名無しさん:2010/07/04(日) 00:39:12
金とってんのか
413デフォルトの名無しさん:2010/07/04(日) 00:39:57
ひとをみたらライターと思え
414デフォルトの名無しさん:2010/07/04(日) 17:20:36
ゲームの販売と同じなら、クソゲー売り続けるのと名作売り続けるのじゃ全く末路が
違うことくらい分かるだろうにアホか
415 ◆0uxK91AxII :2010/07/04(日) 20:15:36
>>401
記事を書いている本人が明らかに知識不足で、可笑しい。
テキトーに眺めただけで、コイツはダメだって分かるレベル。
416デフォルトの名無しさん:2010/07/04(日) 20:54:04
並列化したプログラムの例として、アトミックな足し算使った合計計算のコードを出すような人だからな。
何がしたいのかさっぱりわからんレベル。
ほんとにまともなマルチスレッドのプログラム書いたことあるんかと。
417デフォルトの名無しさん:2010/07/04(日) 21:44:51
>アトミックな足し算使った合計計算

とりあえずPageRankみたいな巨大行列計算だと使うんじゃないかな。
並列化というより分散化したいレベルだけど。
418デフォルトの名無しさん:2010/07/04(日) 22:58:48
まともに組んだことがない人の記事だな
419デフォルトの名無しさん:2010/07/05(月) 20:30:55
まあそこまで批判するべきことじゃない
わからないから試すのであって、わかるならする必要はない
まあ公開するならそれなりに検証して見栄を張るべきだとは思うけどねw素直すぎる
420デフォルトの名無しさん:2010/07/05(月) 21:43:17
MTでパフォーマンス出すには、理屈を理解する頭が無いとどうしようもない気はする
421デフォルトの名無しさん:2010/07/05(月) 22:06:11
分からないから試す、にも二通りある
「何が分からないかを分かった上で試す」のか
「何が分からないかも分からないまま試す」のか

まぁ>>401に関しては、ほんとにチラ見しただけでバカ記事っつーか、むしろ真面目に
叩いて貰えてるだけ幸せなんじゃね?
いやマジで、俺ならこんなのに関わる気にもならんわ。
どうせバカ記事書いた本人は「めんどくせぇのに絡まれたわ」程度にしか思わねーんだろ
と思うとなぁ。
422デフォルトの名無しさん:2010/07/05(月) 22:20:05
>>419
この人の並列処理関連のいろいろなブログ記事とかCodeZineの記事ね、
元々ほかの人の並列処理関連の記事の批判から始まってるんだよね。

ばかなこと書いてるやつがいるので俺が訂正してやるって、
ほんとにこういう感じなのね。
で、あの記事なんだわ。
423デフォルトの名無しさん:2010/07/05(月) 22:23:21
>>421
なぜ?氏の指摘はやっぱりおおよそ的を射てる内容なのかな?
424デフォルトの名無しさん:2010/07/05(月) 22:27:57
つうか着々と増え続けとる…
425デフォルトの名無しさん:2010/07/06(火) 19:33:04
へえ
426デフォルトの名無しさん:2010/07/06(火) 20:01:42
ほぉ
427デフォルトの名無しさん:2010/07/07(水) 22:49:02
>まともに組んだことがない人の記事だな
ttp://blogs.wankuma.com/jitta/archive/2009/10/21/182308.aspx

まともに組んだことはあまりないようだなw
428デフォルトの名無しさん:2010/07/07(水) 23:20:11
なぜ?
Posted @ 2010/07/07 22:46
>スレッドの終了を、もうちょっとスマートに待てないのかなぁ?まぁ、動いてるからいいや。

全然よくありません。
Sleep(0)を入れているとはいえ、無駄なループでCPUを使用していては、まともな計測はできません。
コア数以上にスレッド数を増やしても改善していってしまうのは、これも原因なのではないですか?

>おかしいと思ったらできるところまで追求する。それが職人ってもんじゃないですかねー。似非職人はヤーネー。

いくらなんでもこんなこと言いながらこれではダメでしょう。
429デフォルトの名無しさん:2010/07/07(水) 23:44:31
本人に言えよ
430デフォルトの名無しさん:2010/07/07(水) 23:57:00
おまえならできる
431デフォルトの名無しさん:2010/07/08(木) 00:19:44

432デフォルトの名無しさん:2010/07/08(木) 00:24:16
本人?
433デフォルトの名無しさん:2010/07/08(木) 01:19:38
馬鹿が呟いているだけだから無視でいいだろ。話題にすらならん。
434デフォルトの名無しさん:2010/07/08(木) 01:42:21
ヲチスレじゃないしな
もう少しマシな話題ならともかく、内容がどうでもよさすぎる
435デフォルトの名無しさん:2010/07/08(木) 01:58:28
最近話題がない
436デフォルトの名無しさん:2010/07/08(木) 02:29:13
くだらないネタで流れるなら止まってた方がずっといい
437デフォルトの名無しさん:2010/07/09(金) 11:00:47
マルチスレッドと関係ないかもしれないけど、
CPUって忙しくないときどんな状態になってるんですか?
割り込み待ち状態なんですか?
それともなんらかの無限ループ状態なんですか?
438デフォルトの名無しさん:2010/07/09(金) 12:15:51
忙しくなさ次第でいろいろ
439デフォルトの名無しさん:2010/07/09(金) 21:49:46
>>437
ちょっと暇なときは、いっしょうけんめいだらだらしてる。
だいぶ暇なときは、夢の国へいく。
440デフォルトの名無しさん:2010/07/09(金) 21:49:51
>>438
アイドリング状態
441デフォルトの名無しさん:2010/07/09(金) 22:03:35
442デフォルトの名無しさん:2010/07/09(金) 23:35:26
443名無しさん@そうだ選挙に行こう:2010/07/10(土) 06:31:23
>>440
それじゃ何の説明にもなってない
つーか環境次第で千差万別だから、本気でそういう情報が必要なら仕様書を当たるといい
単に何となく興味があって聞いてみた程度なら、めんどくさいから知らなくていい

仮にx86なら、暇になったらHLTかPAUSEを仕込んでおくことが多いだろうけど、そうで
ないのもあるし、単純にHLT発行すればいいって話でもないし、そもそもぶっちゃけた話、
全く知らない奴に頭っから全部説明してらんね
halt状態の休み方も何段階もある訳だし
444デフォルトの名無しさん:2010/08/12(木) 12:18:23
>ちょっと暇なときは、いっしょうけんめいだらだらしてる。
スピンロックか
445350:2010/08/17(火) 20:53:09
「マルチスレッド」の説明する時に「マルチタスク」の状態遷移持ち出す奴がいて、俺的には「?」なんですが、そういうのありなんですか?
446デフォルトの名無しさん:2010/08/17(火) 21:25:38
プロセス空間が分かれていない頃の書籍でマルチタスク学んだ人なら普通じゃね?
447デフォルトの名無しさん:2010/08/17(火) 21:34:57
>>445
大して難しい話じゃ無いし、基本だから知っておくべきだろう。
448デフォルトの名無しさん:2010/08/17(火) 22:30:37
リアルタイムOSの「タスク」は、Unixのスレッドのようなものだったりするぞ。
449デフォルトの名無しさん:2010/08/21(土) 13:56:10
>「マルチタスク」の状態遷移
て何ぞね
DORMANT/WAITING/RUNNINGとか言った類類の話ならタスク単体の状態だし
タスク同士の関係は非同期というのがマルチタスクの本性であるからして、
複数タスクに渡る状態など一般には規定しようがない

設計者がタスクそれぞれに明示的に同期ロジックをプログラムしたという想定で、
その詳細が明かにされた上でなら話は別だが
450デフォルトの名無しさん:2010/08/29(日) 12:59:13
まあ、>>445は理解できなかったって言ってるんだから説明も出来ないだろう
451デフォルトの名無しさん:2010/10/01(金) 17:29:29
あんまり理解できてないのでうんこみたいな質問申し訳ないんだけど、
スレッドが二つ(A,B)あって、
変数 int a にスレッドAがひたすら数字を入れて、スレッドBはひたすらその数字を読むだけの場合、
int aの書き込み・読み込み時にクリティカルセクション使う必要はある?
手元で試してみたら片方が読み込みオンリーの場合正常に動いたんよね
452デフォルトの名無しさん:2010/10/01(金) 18:10:07
移植性のあるコードを書こうと思ったら必要なる。
ただハードやOS・言語・コンパイラ・ライブラリなどが想定するメモリモデル
(平たく言えばマルチスレッドでメモリがどう見えるかのルール)によっては
それで正しいケースもある。
具体的な回答が欲しいならpthread、Win32のスレッド、Javaや.NETくらいの
くくりで質問するといいよ。
453デフォルトの名無しさん:2010/10/01(金) 18:34:06
>>451
まず、書き込まれた値が化けたりせず正常に読めるか、という点については
適切にアラインされている、CPUのワードサイズ以下の値なら、まず問題ない。
Cコンパイラにおいて、「int」として扱われる値を
Cコンパイラに配置させる場合は、まず大丈夫。

ただし、スレッドAが書き換えた後にスレッドBが読み出したとき
直前の変更が適切に反映されているかどうか、については
環境依存、というか普通は保証されない。
454デフォルトの名無しさん:2010/10/01(金) 18:41:34
一方通行なら問題ないでしょ
455デフォルトの名無しさん:2010/10/01(金) 18:44:58
他に受け渡すデータが一切どこにも何もなくて、ただその数字1個を渡せばいいだけなら
456デフォルトの名無しさん:2010/10/01(金) 18:49:48
ハード依存OKということならシングルCPUのPCは
スレッドに関するほとんどの問題発生しないし正常に動くね。
457デフォルトの名無しさん:2010/10/01(金) 18:55:25
読み出しで値を比較するときはちょっと考えないといけないかも
458デフォルトの名無しさん:2010/10/01(金) 18:57:15
>>456
いくらなんでも、理解して無さすぎ
459デフォルトの名無しさん:2010/10/01(金) 18:57:30
>>452
すまん、VC++で、Win32APIのCreateThread使った話だった

>>453
thx 直前の変更は特に気にしなくてもよさそう

取り扱う変数がvectorとかlistになってくるとまた違うんかな……
460デフォルトの名無しさん:2010/10/01(金) 22:14:34
ひたすらスレッドAが書き込んでスレッドBが読み出してprintfするだけなら正しく見えるが、
例えば、イベントを受け取ってスレッドAが書き込もうとして、スレッドBは読み出すとき、
読み出された値はスレッドAが書き込こむ前か後かはCPUの気まぐれになりそうな気がする。
まぁそんな時はロックしなくてもスレッドAが書き込み終わったらスレッドBに読み込むように言えばいいけど
461デフォルトの名無しさん:2010/10/01(金) 22:32:14
Win32での32bit読み書きはアトミックな操作だっけ?
462デフォルトの名無しさん:2010/10/01(金) 22:38:21
Windowsならここ読んどきゃいいよ
http://msdn.microsoft.com/ja-jp/library/bb310595(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ee418650(VS.85).aspx
463デフォルトの名無しさん:2010/10/02(土) 04:07:15
>>461
Win32の環境じゃなくIA32とかx64の意味でじゃないの?
464デフォルトの名無しさん:2010/10/02(土) 10:36:20
i386SXのように外部データバスが16bitのものはどうなるんだろ。
i386SXでマルチプロセッサ構成は見たことがないけどね。
465デフォルトの名無しさん:2010/10/02(土) 10:56:16
たぶん、データが化ける可能性があると思う。
386SX以外にも、68000とか8088とかがその系統だったと思うし
今後も組み込み向けとかにそういうのが出てこないとは言い切れない。

だから、「intなら大丈夫」じゃなくて「intなら普通は大丈夫」程度。

とはいえ、組み込み向けのバス幅制限があるような環境では
マルチスレッドはともかく、
マルチプロセッサ/マルチコアはまずありえないと考えて良いんじゃないかな。
466デフォルトの名無しさん:2010/10/02(土) 11:02:40
そもそも、lock prefix使えないはずなので、マルチプロセッサが構成出来ない。
467デフォルトの名無しさん:2010/10/02(土) 11:03:07
386SXの32ビットR/Wや8088の16ビットR/Wは、読み書きは複数サイクルかもしれないけど、
完了するまで割込まれないんじゃなかった? 仕様書見て言ってるわけじゃないけど。

同じような構成で割込まれるプロセッサもあるかもしれないけど。
468デフォルトの名無しさん:2010/10/02(土) 11:50:37
32bitのアクセスがアトミックであると保証されてるのはi486以降とIntelの資料に書いてある
469デフォルトの名無しさん:2010/10/02(土) 12:09:53
>>467
割り込みは確かに発生しないから単一コアのスレッドなら問題はないが、
マルチコア・CPUの場合は問題が発生する。
470デフォルトの名無しさん:2010/10/02(土) 12:18:00
んでi386SXのマルチプロセッサやマルチコアは実在するの?
471デフォルトの名無しさん:2010/10/02(土) 12:46:22
SXかどうかはわからないが386のマルチプロセッサはあったらしい。
http://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%BC%E3%82%AF%E3%82%A8%E3%83%B3%E3%83%88%E3%83%BB%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF

プロセッサレベルの割込みじゃなくて、バスの読み書きがどうかということだと思うんだけど。
472デフォルトの名無しさん:2010/10/02(土) 12:55:16
>>471
それはi386DXだな
473デフォルトの名無しさん:2010/10/02(土) 14:15:52
ハードのことわからんのに憶測で書くなよ
474デフォルトの名無しさん:2010/10/02(土) 15:18:15
>>468
i386まではDMA操作なら割り込めた、CPU単体でならアトミックだったがSXでマルチプロセッサ組んだらダメだろうと思う
475デフォルトの名無しさん:2010/10/02(土) 15:22:14
小数点付きのプログラムカウンタのあるCPUでも使ってるんかね
476デフォルトの名無しさん:2010/10/02(土) 22:16:44
>>475
パイプラインの途中を指し示したいみたいな?
477デフォルトの名無しさん:2010/10/02(土) 23:05:16
たぶん475は、全ての命令が1クロックで実行できると思ってる。
478デフォルトの名無しさん:2010/10/02(土) 23:52:07
intelのは1クロックで動くんじゃないの
479デフォルトの名無しさん:2010/10/02(土) 23:58:09
ワイヤードロジックをほぼ全体に使うようになったのは486から
480デフォルトの名無しさん:2010/10/03(日) 00:08:11
>>467
割り込みと、トランザクションをごっちゃにしてる?
CPUの割り込みはR/Wの間に中断しないだけ。
マルチプロセッサについてはRとWが別のトランザクションなんでR/Wの間に別のプロセッサのRやWが割り込める。
この割り込みを防ぐ信号を駆動するのがインターロック命令
481デフォルトの名無しさん:2010/10/03(日) 01:17:48
482デフォルトの名無しさん:2010/10/03(日) 11:49:42
読む側が、変更されない変数読んでると思われて最適化されちゃうとか無いの?
volatile付けなくても大丈夫?
483デフォルトの名無しさん:2010/10/03(日) 13:45:17
>>482
スレッド間で共有する変数はvolatileつけておくべきだよ。
484デフォルトの名無しさん:2010/10/03(日) 14:19:19
>>483
そんないいかげんな知識で大丈夫か?
485デフォルトの名無しさん:2010/10/03(日) 14:31:25
馬鹿は黙れ。CPUの基本構造も知らずにプログラム組むとか笑えない。
486デフォルトの名無しさん:2010/10/03(日) 14:33:44
>>484
完璧な解説ヨロ
487デフォルトの名無しさん:2010/10/03(日) 14:50:17
ここ読んどけ
http://d.hatena.ne.jp/bsdhouse/
488デフォルトの名無しさん:2010/10/03(日) 14:58:02
>>465
> とはいえ、組み込み向けのバス幅制限があるような環境では
> マルチスレッドはともかく、
> マルチプロセッサ/マルチコアはまずありえないと考えて良いんじゃないかな。

組込み マルチコア でググレばわかるように、もはや組み込みでもマルチ
コアはありえないと言える状況ではないよ。
489デフォルトの名無しさん:2010/10/03(日) 15:10:07
8088やi386SXみたいな内部と外部でバス幅が違うような
石を使わざるを得ない(特殊な?)状況限定の話にそんなレスされても。
490デフォルトの名無しさん:2010/10/03(日) 16:00:49
内部と外部でバス幅が違うなんて組み込みだと今時珍しくないが
もしかしてそんなことも知らんのか?
491デフォルトの名無しさん:2010/10/03(日) 16:58:51
ハードの事わかって書いてるわけじゃないでしょ
最適化されたときのコードの矛盾とかをハードの問題みたいに思ってるのかも
492デフォルトの名無しさん:2010/10/03(日) 19:47:54
【OS】 Linux,W2K
【言語】 C
【実行環境】Cygwin(W2Kの場合)
【その他特記する事項】 以下の行列演算は高速化できるのでしょうか。
スレッドの意味も作り方もわかりません。
for(j=0;j<16;j++){
for(i=0;i<16;i++){
d1[j]^=GF[e1[j][i]];
d2[j]^=GF[e2[j][i]];
}
}
493デフォルトの名無しさん:2010/10/03(日) 20:23:30
>>492
それCでコンパイルできた?
494デフォルトの名無しさん:2010/10/03(日) 20:29:53
>>488>>490
「バス幅が違うような環境でマルチコアなんかないだろ?」と
>>465には書かれているように見えるが
おまえ、日本語は苦手か?

両方を満たしたものがめずらしくもないものなら
そう反論しろよ。別個にではなく。
495デフォルトの名無しさん:2010/10/03(日) 20:30:43
>>492
またお前か
496494:2010/10/03(日) 20:38:18
ちょっと書き方を変える。

>>488
「組み込みにマルチコアはありえない」などとは、どこにも書かれてない。
偉そうにしてるが、幻覚でも見たのか?

>>490
「内部と外部でバス幅が違う環境などない」などとは、誰も言ってない。
偉そうにしてるが、電波でも受け取ったか?


「内部と外部でバス幅が違うような用途でも、マルチコアが採用されつつある」
と言いたいのなら、ちゃんとそう書け。
497デフォルトの名無しさん:2010/10/03(日) 22:28:11
> 「組み込みにマルチコアはありえない」などとは、どこにも書かれてない。
⇒ 「マルチプロセッサ/マルチコアはまずありえない」と書いてますが?

>「内部と外部でバス幅が違う環境などない」などとは、誰も言ってない。
誰もそんなことは言ってないし、誰もそれに反論なんてしてない。
むしろ、最近は珍しくないと書いてあるんだが。

偉そうにしてるが、一体誰と戦ってるんだ? (w
498 ◆0uxK91AxII :2010/10/04(月) 23:01:18
>>484
大丈夫だ、問題無い。
499デフォルトの名無しさん:2010/10/05(火) 22:30:40
>>498
インテルは言っている、素直にインテル・スレッディング・ビルディングブロックを使えと
500デフォルトの名無しさん:2010/10/06(水) 01:31:55
インテルは言っている、インテルはいっている
501デフォルトの名無しさん:2010/10/06(水) 09:05:27
エルシャダイスレはここですか?
502デフォルトの名無しさん:2010/10/06(水) 19:27:08
だめええ!入れないでえええ!インテルいれちゃだめええええええええ!!あ?
503デフォルトの名無しさん:2010/10/06(水) 21:54:44
インテルは逝ってる
504デフォルトの名無しさん:2010/10/10(日) 11:00:31
スタベーションを回避する方法を教えてください。
505デフォルトの名無しさん:2010/10/12(火) 15:22:11
待ち行列の先頭にいるスレッド以外は偶然入れても待ち行列の最後に並んで前の人が終わるまで待つとか
506デフォルトの名無しさん:2010/10/12(火) 20:17:24
>>504
A,B,Cというセマフォを取得するときどのスレッドもA,B,Cの順でセマフォを取得する。
507デフォルトの名無しさん:2010/10/13(水) 01:49:19
【OS】WindowsXP
【言語】C++,Win32
【実行環境】VisualStudio2005

かなり基本的な質問です。
スレッドを外部から終了させたい場合、どのようにすればいいのでしょうか?
あるスレッドを常に動かしていて、ユーザーがGUIプログラムを閉じた場合に、メインスレッド側からどのように命令すればいいのかわかりません。
ttp://msdn.microsoft.com/ja-jp/library/kdzttdcb%28VS.80%29.aspx
↑のようなページやググって調べると、スレッド関数側が自発的に_endthreadex関数などで終了する例はあるのですが、
終了するタイミングをスレッド関数側が知らない場合についてはあまり書かれていません。
よろしくお願いします。
508デフォルトの名無しさん:2010/10/13(水) 02:06:21
終了するタイミングをスレッド関数側に教える仕組みがいくつかある
509デフォルトの名無しさん:2010/10/13(水) 06:37:16
>>507
何とかしてサブスレッドに終了を伝える方法を自分で実装する。特に関数はない。
Windowsならvolatile boolかCreateEvent+SetEventでいいだろう。
510デフォルトの名無しさん:2010/10/14(木) 04:23:26
いいか、お前らTerminateThreadは使うなよ!使うな!絶対に使うなよ!
511デフォルトの名無しさん:2010/10/14(木) 07:47:26
kill -KILLですね、わかります。
512デフォルトの名無しさん:2010/10/14(木) 22:51:22
TerminateThread = ハングしろ に近いからねぇ
.Netとかだとそもそも抹消されてるが。Suspendも割と個人的に怖いな
513デフォルトの名無しさん:2010/10/14(木) 22:52:08
TerminateThreadに頼ったプログラムは死んでいいけど、
バグがあってサブスレッドが応答しなくなった時の万が一のためにTerminateThreadするのは
いーんでないの
514デフォルトの名無しさん:2010/10/14(木) 23:08:49
つーかスレッドの終了待ちでWaitFor*Objectしてタイムアウトしたら
TerminateThreadってのは普通だろ
515デフォルトの名無しさん:2010/10/14(木) 23:23:24
そりはバグなので速やかにアプリケーションを終了すべきでは?
少なくとも普通じゃない。
516デフォルトの名無しさん:2010/10/14(木) 23:43:40
>>510
別に使っても問題ないよ。
DllMainのデタッチスレッドさえちゃんと実装されていれば何も問題はない。
517デフォルトの名無しさん:2010/10/14(木) 23:58:39
Vistaより前がターゲットに入るなら「何も問題ない」は無いわ
DllMainがどう頑張ろうと関係無い
518デフォルトの名無しさん:2010/10/15(金) 00:15:38
>>516
DllMainはコールバックされないってちゃんと書いてあるのにどういうコードを書くつもりなのか聞きたい
519 ◆0uxK91AxII :2010/10/15(金) 04:13:54
TerminateThreadするくらいならExitProcessで止めを刺す。
520デフォルトの名無しさん:2010/10/15(金) 04:18:38
TerminateThreadなんて使う必要性あるの?
521デフォルトの名無しさん:2010/10/15(金) 06:53:29
サブスレッドの確保したメモリとかソケットとかDB接続とかその他もろもろのハンドル
はどうするつもりだよ。
あとミューテックスをロックしたまま暴走した場合とか開放されるんだっけ?
問題ありすぎ
522デフォルトの名無しさん:2010/10/15(金) 23:13:04
>>514
ないない
523デフォルトの名無しさん:2010/10/15(金) 23:13:49
>>519
そのほうがごみが残らなくていいな
524デフォルトの名無しさん:2010/12/19(日) 17:17:41
printfはどういうレベルでスレッドセーフじゃないんでしょうか
525デフォルトの名無しさん:2010/12/19(日) 17:19:00
間違えた、sprintfです
526デフォルトの名無しさん:2010/12/19(日) 17:22:56
書込み先のことかな?
527デフォルトの名無しさん:2010/12/19(日) 17:24:15
処理系によるんじゃないでしょうか
528デフォルトの名無しさん:2010/12/19(日) 17:30:04
MT-Safe ってどういう意味?
529デフォルトの名無しさん:2010/12/19(日) 17:30:49
複数のスレッドで安全という意味
530デフォルトの名無しさん:2010/12/19(日) 17:32:51
>>527
POSIXというか、ぶっちゃけLinuxの標準ライブラリstdioでならどうでしょうか。
ここまで範囲限定したらスレチになんのかな?
531デフォルトの名無しさん:2010/12/19(日) 17:35:10
POSIXのstdioで _unlocked が付いてないものはスレッドセーフです
532デフォルトの名無しさん:2010/12/19(日) 19:46:28
つまりprintfはスレッドセーフってことか。ありがとう!
533デフォルトの名無しさん:2010/12/19(日) 21:15:28
関数がってことで、使い方間違えると...
534デフォルトの名無しさん:2010/12/19(日) 23:13:56
まぁ想像するだけでもprintfは外部に出力するからロックとか色々してるのは分かる
printfしたらバグが起こらなくなったとかで原因がスレッド絡みとかよくある

んでprintfで起こらなくなるから放置とかマジ勘弁してくださいorz
535デフォルトの名無しさん:2010/12/24(金) 00:47:37
スレッドセーフなメモリの読み書きについて勉強しているのですが、情報が少なく捗りません。
メモリへの同時アクセスによるデータ破壊は、書き込み時にのみ起こると認識しているのですが、正しいでしょうか?

・二つのスレッドが一つの変数を書き換えるとき
 →データが破壊される場合がある。
 
・一つのスレッドが一つの変数を書き換え、別のスレッドがその変数を読み込むとき
 →書き込みは問題なく行われる。
 →読み込みは、書き換え途中のデータを読み込む場合がある。

・二つのスレッドが一つの変数を読み込むとき
 →問題なし。
536デフォルトの名無しさん:2010/12/24(金) 01:06:26
書き込まないものを読み込むことにどんな意味があるのだろうか
537デフォルトの名無しさん:2010/12/24(金) 01:10:53
const 定数ですね
538デフォルトの名無しさん:2010/12/24(金) 01:43:18
>>535
いずれも正しい。
539デフォルトの名無しさん:2010/12/24(金) 06:02:20
ありがとうございます。理解が深まりました。
540デフォルトの名無しさん:2010/12/24(金) 09:17:21
>>535
> ・二つのスレッドが一つの変数を書き換えるとき
>  →データが破壊される場合がある。

データの破壊とは何ぞや?単に後から書いたデータが残る。それだけの話。
541デフォルトの名無しさん:2010/12/24(金) 09:53:16
それぞれの書き込みがアトミックならね。

32ビットマシンで64ビットの書き込みとか、アトミックでない場合、破壊が起こるかもしれない。
542デフォルトの名無しさん:2010/12/24(金) 15:07:31
>>540
配列だって、立派な配列変数だぜ。
文字列型変数もあるしな。
543540:2010/12/24(金) 15:52:35
そうだった、最近のデータはでかいんだな。
組み込み系のスレ見た後だったから頭がアセンブラレベルになってた。
失礼。

俺はどっちにしてもミューテックスかクリティカルセクションで排他しておくけど。
544デフォルトの名無しさん:2010/12/24(金) 17:17:54
同時アクセス時の挙動なんてCPUの仕様次第だろ
同時読込なら安全なんて確証は無い
545デフォルトの名無しさん:2010/12/24(金) 17:20:04
データが小さければ読み書きのキャッシュ問題とか無視できるが、
今はふつうに扱う標準データが大きいからなあ。プログラミングも大変だ。
546デフォルトの名無しさん:2010/12/24(金) 17:20:27
アホ発見
547デフォルトの名無しさん:2010/12/24(金) 17:30:42
同時読込なら安全なんて確証は無い・・・
ということは同じ関数を同時に実行するとまずい場合があるってことか
同じ関数を同時に実行すると同じ命令列を同時に読込むことになるもんな
548デフォルトの名無しさん:2010/12/25(土) 20:23:56
言語仕様じゃなくハードウェア仕様だと理解してればいい
大丈夫かどうかを言語仕様で調べても守備範囲外のことで規定されてないから無駄
549デフォルトの名無しさん:2010/12/25(土) 20:28:39
いや失礼、言語仕様で規定されてる物もあるか
550デフォルトの名無しさん:2010/12/26(日) 16:17:56
printfがスレッドセーフじゃないのはわかるけど
どうしてsprintfがスレッドセーフではないのはなぜ?
551デフォルトの名無しさん:2010/12/26(日) 16:24:32
>>550
内部にスタテックバッファーを持ってるかも。
552デフォルトの名無しさん:2010/12/26(日) 16:54:42
>>551
まじか・・・だらしのないやつだなsprintfも・・・
553デフォルトの名無しさん:2010/12/26(日) 17:45:40
おまえが使ってるライブラリを実装したところに聞けよ
554デフォルトの名無しさん:2010/12/26(日) 18:09:36
sprintfがスレッドアンセーフってのはどこ情報?
555デフォルトの名無しさん:2010/12/26(日) 19:50:50
あとだしで申し訳ないがライブラリはglibcです

>>554
ttp://slashcolon.com/wordpress/2007/12/25/
ttp://www.kmonos.net/alang/d/2.0/ctod.html#printf
Dでスレッドセーフにしました=Cだとスレッドセーフちがう
と解釈しました

ていうか、そもそもprintfがスレッドセーフだという情報がない。
不明なうちはアンセーフ扱いするのが俺のジャスティス
556デフォルトの名無しさん:2010/12/26(日) 20:00:44
なるほど
確かに
557デフォルトの名無しさん:2010/12/26(日) 20:13:26
それ英語版見たらスレッドセーフなんてどこにも書いてないぞ・・・
> writefln() improves on printf() by being type-aware and type-safe:
誤訳じゃないのか
558デフォルトの名無しさん:2010/12/26(日) 20:16:54
ttp://stackoverflow.com/questions/467938/stdout-thread-safe-in-c-on-linux
適当にぐぐったけどglibcはスレッドセーフとか書いてるような感じ
559デフォルトの名無しさん:2010/12/27(月) 11:09:50
へえ
560デフォルトの名無しさん:2010/12/27(月) 14:34:33
探しても「セーフだろう」「たぶんセーフ」ばっかりしか出てこない
むずむずするなぁ
561デフォルトの名無しさん:2010/12/27(月) 15:03:50
IEEE Std 1003.1-2001の定義では、例外的にアンセーフで良いとされているもの以外は
スレッドセーフ。

http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html
562デフォルトの名無しさん:2010/12/28(火) 19:19:26
過去スレ全部はみれなかったんだけど、マルチスレッド関連の良書をまとめてみる。
この他にこれがいいとかあったり、これ駄目とかあったら教えて。


[一般]
並行コンピューティング技法 ―実践マルチコア/マルチスレッドプログラミング

The Art of Multiprocessor Programming 並行プログラミングの原理から実践まで

増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編


[java]
Javaスレッドプログラミング―並列オブジェクト指向プログラミングの設計原理 (OO SELECTION)

Concurrency: State Models and Java Programs 2edition

Java並行処理プログラミング ―その「基盤」と「最新API」を究める


[windows]
Win32 マルチスレッド プログラミング

Advanced Windows 第5版 上
Advanced Windows 第5版 下


[Unix]
POSIXスレッドプログラミング

563デフォルトの名無しさん:2010/12/31(金) 19:52:51
[C++]
インテルスレッディング・ビルディング・ブロック

主にこのライブラリの使い方だが、
他にもスレッド管理の考え方が載ってる。まぁオープンソースなので見れるのだけど
564デフォルトの名無しさん:2011/01/03(月) 21:56:27
ありがとうございます。C++の良書をあまり知らないので助かります。
565デフォルトの名無しさん:2011/01/15(土) 09:14:58
concurrent hashmapのC++実装って
なんでないの?
566デフォルトの名無しさん:2011/01/15(土) 09:49:16
>>565
キミのためにお取り置きしてある。
567デフォルトの名無しさん:2011/01/15(土) 10:31:02
>>566
並列mapでいいから実装ないの?
C++って並列コンテナないから何もできないよね
568デフォルトの名無しさん:2011/01/15(土) 18:21:33
>>567
キミが作るだろうと思って残しておいた。
569デフォルトの名無しさん:2011/01/16(日) 11:14:37
>>567
俺のところにはある。
570デフォルトの名無しさん:2011/01/16(日) 11:28:44
C/C++はアセンブラと高級言語の間みたいな位置だからな
言語そのものを作るとか、OSを作るとか、リソースの厳しい組み込み系で作るとか、
そういう用途じゃないなら別に強力な言語ではない
ネイティブのCPUの挙動を理解しないとC/C++の有用性は半減すると思われ
571デフォルトの名無しさん:2011/01/25(火) 23:02:03
すみません、spin-lockをしている間にCPUの使用率を下げる方法を知っている方はいますか?
調べてみると、rep;nop命令やSSEのpause命令をがそれに該当するように思えるのですが、
使ってみても何ら変わりませんでした。
スピンロックつかっわないとは思うんだけど。
自作のスレッドバリア関数(自作のspin_lock)を作って、
たとえば、
if(threadnum=5) sleep(10);
my_barirrer();
とするとスレッド5を待っている間は5以外のCPU使用率が100%近くなってしまいます。
それに対してOpenMP使った場合では、
if(threadnum=5) sleep(10);
#paragma omp barirrer

だと待っている間はCPU使用率は殆ど変わりません。
ちなみに自作のspinlockは下記のような感じです。
if(thread_num == 0)
{
asm volatile(
"Loop1:\n\t\t"
"movl (%0), %%eax\n\t\t"
"movl (%1), %%ebx\n\t\t"
"lfence\n\t\t"
"cmpl %%ebx, %%eax\n\t\t"
"rep;nop\n\t\t"
"jne Loop1\n\t\t"
:
:"r"(&lock->sync), "r"(&lock->maxthreads)
:"memory","%eax","%ebx"
);

というか、これって間抜けですかね?
572デフォルトの名無しさん:2011/01/25(火) 23:10:46
自前でタスク切換えみたいなことするしか
573デフォルトの名無しさん:2011/01/25(火) 23:15:42
574デフォルトの名無しさん:2011/01/25(火) 23:24:51
>>573
お前友達いないだろ
575デフォルトの名無しさん:2011/01/25(火) 23:34:47
>>571
Sleepさせりゃいいんじゃね。
576デフォルトの名無しさん:2011/01/25(火) 23:44:45
割り込みでしか切り替わらないコードで使用率下げたいというのが
577デフォルトの名無しさん:2011/01/28(金) 22:22:30
さむいな(´・ω・`)
578デフォルトの名無しさん:2011/01/28(金) 22:43:23
寒稲
579デフォルトの名無しさん:2011/01/31(月) 22:10:29
>>571
CPU使用率が100%じゃないロックなんて、スピンロックとは認めない。
580デフォルトの名無しさん:2011/02/01(火) 00:53:40
そもそも100%じゃないってことはコンテキストスイッチしてるってことになるでしょ?
何のためのスピンロックなのよあり得ない。
581デフォルトの名無しさん:2011/02/01(火) 10:50:42
スリープロックのループもスピン扱いすることもあるから何とも
582デフォルトの名無しさん:2011/04/04(月) 19:37:25.20
ちょっと聞いていい?

以下のコードでnotifyAllされたらどうなるのって質問

void A()
  synchronized(Lock){
    if(List.size() == 0){
      try{ Lock.wait(); }(Exception e){}
    }
    //以下処理続く
  }
}

このコードで複数のスレッドが待ち状態だったらnotifyAllとき再度Lockを取りに行ってくれるの?
もし、そうだったとしたら。
結局はnotifyで1つのスレッドのみ動かすってのと同じことになるの?

それとも再起処理的に以下のようにしなきゃだめ?
void A()
  synchronized(Lock){
    if(List.size() == 0){
      try{ Lock.wait(); }(Exception e){}
      A(); ←ここでさらに再帰的に同じメソッドを呼び出す
    }
    //以下処理続く
  }
}

おしえてエロイひと。。。
583デフォルトの名無しさん:2011/04/04(月) 19:47:38.94
>>582
notifyAll を呼ぶと、wait してたスレッドはすべて起きて、 Lock を取りに行く
どうせみんなすぐには取れないから Lock 待ち状態になるが、すでに wait からは外れてるので、 Lock を取れた順にすべてのスレッドが動き出す

notify の場合は、wait してたスレッドのうちひとつだけが起きて Lock を取りに行く
他のスレッドは、その後 Lock が空いても、眠ったまま起きない

wait はふつう再帰じゃなくて while にする
synchronized (Lock) {
 while (List.size() == 0) {
  Lock.wait();
 }
}
waitは、notifyされてなくても間違って起きることがあるらしいので、このように書くべきこととされている
584デフォルトの名無しさん:2011/04/04(月) 20:17:38.60
>notifyAll を呼ぶと、wait してたスレッドはすべて起きて、 Lock を取りに行く
ということはnotifyAllでそのまま下に処理が流れていくんじゃなくて

再度 synchronized(Lock){ ←この部分に処理が戻ってくるイメージなんですかね?

別のメソッド内の以下のようなコードでnotifyAllをかけようと思ってたんだけど、
ちゃんとnumの個数分以上のスレッドは再度、wait状態に入ってくれるのか心配でした
  for(int i = 0 ; i < num ; i++){
    List.add(object);
  }
  Lock.notifyAll();

それと。
 while (List.size() == 0) {
   Lock.wait();
 }
これしなきゃいけないんですね。Javadoc見てきました。

>>583 ありがとー。
585デフォルトの名無しさん:2011/04/04(月) 21:55:04.24
>>584
synchronized のところまで戻るわけじゃなく、synchronized の中にいるまま、 wait のところで、
Lock をいったん解放、おやすみなサイして、起きたら元通りに取りにいく
wait は synchronized の中でありながら Lock を手放している特殊な場所

notifyAll を呼んだ側のスレッドは、notifyAll を呼んだあとそのまま下に流れていく
というのも、notifyAll を呼んだ時点では Lock は notifyAll 側のスレッドが握ってるので (synchronized 中のはず)、
wait 側のスレッドは起きるけれども、Lock を取れない
notifyAll 側が synchronized から抜けるなりして Lock を解放すると、wait 側が Lock を取って動き出せるようになる
586デフォルトの名無しさん:2011/05/25(水) 01:36:55.92
質問です
CreateThreadで複数のスレッドを作ったときに渡したパラメータは
スレッドごとに別々のものを渡してもいずれ同じものに書き換えられてしまうと思うんですけど
これをスレッドごとに別々のままにしてやるにはどうしたらいいのでしょうか
VCなら__declspec(thread)をつけるとTLSが使えると読んだのですが
これをCreateThreadに渡すThreadProcのどこで使えばいいのかわかりません
587デフォルトの名無しさん:2011/05/25(水) 03:14:14.44
>いずれ同じものに書き換えられてしまう
そういうことをやってるだけでしょ
588デフォルトの名無しさん:2011/05/25(水) 08:33:13.11
>>586
お前がやってんのは
int a;
int* b = &a;
int* c = &a;
int* d = &a;
のb,c,dが別々のものと言ってるのと同じだろ
589デフォルトの名無しさん:2011/05/25(水) 08:38:22.51
あーなるほど、同じ場所(=ポイント先)を渡して「別々のもの」と言い張っているのか。
590デフォルトの名無しさん:2011/05/25(水) 11:41:30.98
forkってスレッドセーフ?
591デフォルトの名無しさん:2011/05/25(水) 11:56:15.17
592デフォルトの名無しさん:2011/05/25(水) 21:24:18.36
別のポインタ渡したつもりで同じものを渡していたことに気づいて悲しくなりました
お手数おかけしました
593デフォルトの名無しさん:2011/06/23(木) 08:39:51.24
スレッドって、毎秒ごとに数百回の開始と終了を繰り返すような使い方は正しいの?
それとも、必要な時だけスレを立てる使い方じゃなくて、
スレは基本的に立てっぱにしといて、用がある時にメッセージ等を送るという使い方をすべき?
594デフォルトの名無しさん:2011/06/23(木) 08:45:48.47
スレッドの開始はそれなりにコストの大きい処理だから
スレッドプールにするのが正解
595デフォルトの名無しさん:2011/06/23(木) 08:49:17.54
なるほど。直観的じゃないのな。
596デフォルトの名無しさん:2011/06/23(木) 09:10:49.87
用途によるよ。一度スレッドを起動したら数十秒は戻ってこないならプールしなくても大差ない。
597デフォルトの名無しさん:2011/06/23(木) 09:47:04.06
593の前提と変わってるじゃんか
598デフォルトの名無しさん:2011/06/23(木) 22:41:08.11
>>593
同時に起動できるスレッドの数ってそんなに多くないしな。
32bit、Windowsだと2000個くらい(スタックサイズ標準の場合)
599デフォルトの名無しさん:2011/06/24(金) 00:22:34.83
スレッドの生成は5ミリ秒くらいのオーバーヘッドあるだろ。
数百回やるなんて頭おかしい

>>598
今時32ビット縛りなんて考える必要なくね?
600デフォルトの名無しさん:2011/06/24(金) 05:23:53.79
5msec!
601デフォルトの名無しさん:2011/06/24(金) 10:49:09.11
なにそのみずほ銀行
602デフォルトの名無しさん:2011/06/24(金) 10:53:32.07
ミリ秒はつらいな・・・
と思ったけど16ビット機なら仕方ないか。
603 ◆0uxK91AxII :2011/06/24(金) 17:27:33.68
手元の環境だと、threadの生成と実行開始のどちらも0.1[ms]すら掛からないね:)
604デフォルトの名無しさん:2011/06/25(土) 01:58:06.76
XPからスレッド生成が凄く速くなった記憶がある
605デフォルトの名無しさん:2011/06/25(土) 17:22:00.98
じゃあ0.1msでスレッド生成するコード晒してみろよ
606 ◆0uxK91AxII :2011/06/25(土) 18:39:30.70
Win32のCRTにある_beginthread。
生成は0.1[ms]未満、実行開始はコンパイラかライブラリに依存で0.1[ms]台からに訂正。

#include <Windows.h>
#include <stdio.h>
#include <process.h>
struct perf {LARGE_INTEGER freq;LARGE_INTEGER t0;};void __cdecl thread(void *
pArg){perf *pperf;LARGE_INTEGER t1, d;QueryPerformanceCounter(&t1);pperf = (perf
*)pArg;printf("thread: %I64d\n",t1.QuadPart-pperf->t0.QuadPart);}int main(){
LARGE_INTEGER f={0}, t0, t1, d;perf perf;QueryPerformanceFrequency(&f);printf(
"freq: %I64d\n", f.QuadPart);perf.freq = f;QueryPerformanceCounter(&t0);perf.t0
= t0;_beginthread(thread, 0, &perf);QueryPerformanceCounter(&t1);printf(
"main: %I64d\n", t1.QuadPart-t0.QuadPart);Sleep(1000);return 0;}
607デフォルトの名無しさん:2011/06/25(土) 22:55:22.93
>>606
5764ticks/272758=2.1ms。
一桁違ってないか?どんだけ速いマシン使ってんの
608607:2011/06/25(土) 23:17:06.14
訂正。
 誤:5764ticks/272758=2.1ms
 正:5764ticks/2727568=2.1ms

処理のスループットが問題なんだからJOINの時間も入れよーぜ。
あと、>>606はmainが先に終わると不正メモリアクセスになる糞コード
609デフォルトの名無しさん:2011/06/26(日) 01:54:34.21
C#だけど2マイクロ秒くらいだよ。
var sw = new System.Diagnostics.Stopwatch();
sw.Start();
for (var i = 0; i < 1000; i++) {new Thread(F);}
decimal time = (decimal)sw.ElapsedTicks / System.Diagnostics.Stopwatch.Frequency;
Console.WriteLine("{0} [ms]", time / 1000 * 1000);
610デフォルトの名無しさん:2011/06/26(日) 02:04:01.25
            ∩_ 
           〈〈〈 ヽ
          〈⊃  }
   ∩___∩  |   |
   | ノ      ヽ !   !
  /  ●   ● |  /
  |    ( _●_)  ミ/ こいつ最高にアホ
 彡、   |∪|  /
/ __  ヽノ /
(___)   /
611 ◆0uxK91AxII :2011/06/26(日) 10:35:46.17
>>607 >>608
Core i7 2600K 3.4[GHz] HTT無効, Windows 7 X64 SP1, Visual C++ 2010 Express

>mainが先に終わると不正メモリアクセスになる糞コード
大丈夫だ、問題ない。

>>609
thread poolだから略。
612デフォルトの名無しさん:2011/06/26(日) 15:21:14.56
>mainが先に終わると不正メモリアクセスになる糞コード
こういうことを平気で書いちゃう人もいるんだな。笑える。
613デフォルトの名無しさん:2011/06/26(日) 15:23:47.45
具体的に反論できない奴のテンプレート的反応で笑える。
614デフォルトの名無しさん:2011/06/26(日) 20:09:29.64
>>611
Xeon E5506 2.13GHzだが0.46msだった。0.1msには及ばない。

>thread poolだから略。
Threadはスレッドプーリングされない。単にStartし忘れているだけ
615デフォルトの名無しさん:2011/06/26(日) 22:10:05.48
node.jsの説明見ているとシングルスレッドなので万歳!みたいな記事が多く混乱してみる
616デフォルトの名無しさん:2011/06/26(日) 23:27:19.63
あれは

『マルチスレッドやマルチプロセスではC10Kに対応できなくね?
俺良い事思い付いた。シングルスレッドでイベントドリブンにしたら良いんじゃね。』

という発想だから、

『あー、でもマルチコアマシンではシングルスレッドだと性能出なくね?
結局ロードバランサとか必須だわな。』

みたいな話をすると、そもそも何でマルチスレッドを否定していたのかという
自己矛盾に陥るので、わざとスルーしているのかもね。ちょっと分かり辛いよね。
617デフォルトの名無しさん:2011/06/26(日) 23:49:28.20
C10Kが騒がれてたのはもう10年くらい前の話で、
その頃は1CPUでシングルコアのマシンが殆どだったしね
61858-3-155-112.ppp.bbiq.jp :2011/06/27(月) 07:39:41.06
リクエスト来る事にスレッド作成してた今までが異常すぎ
C10K問題で破綻するのは今でも一緒ですわい
619 ◆0uxK91AxII :2011/06/27(月) 09:16:36.96
>>614
>Threadはスレッドプーリングされない。単にStartし忘れているだけ
ouch
C#、試してみたら遅すぎた。
Cの4~20倍くらい掛かっている。
620デフォルトの名無しさん:2011/06/27(月) 19:42:02.22
>遅すぎた
0.1msの20倍は2msだろ。
50スレッド生成しても0.1秒、全く問題ないような
621デフォルトの名無しさん:2011/06/27(月) 20:02:07.59
Unix屋なんでWindowsは全く詳しくないけど
スレッド数をむやみやたらを増やしてもオーバーヘッドが多くなるだけでいいことなんてないのでは?
それよりスレッドプールを使った方が管理も簡単だと思うんだけど、Winの開発環境にはもしかしたら
スレッドプールライブラリーみたいなのがなくて自分で仕組みを作らなきゃ駄目なのかい
622デフォルトの名無しさん:2011/06/27(月) 20:04:40.67
スレッドは設計?をよう考えないとハマるだろうに
623デフォルトの名無しさん:2011/06/27(月) 21:44:24.18
>>621
UNIXでよく使われるものはWindowsにもある

と考えてまず間違いない
624デフォルトの名無しさん:2011/06/27(月) 23:29:57.24
スレッドのメリットはスループット性能だけではないのだが。
625デフォルトの名無しさん:2011/06/28(火) 10:33:59.70
メモリ空間が共通なのはデメリットだよね?
626デフォルトの名無しさん:2011/06/28(火) 11:04:08.15
共通じゃないのが欲しければfork→execでいいんじゃね。
627デフォルトの名無しさん:2011/06/28(火) 20:31:14.09
メモリ空間共通のデメリットって、Cでメモリ破壊の危険性を排除できない
ぐらいしか思いつかないんだが。
628デフォルトの名無しさん:2011/06/28(火) 20:40:04.57
・メモリ共有だと、プロセスが落ちたら皆落ちる
・NUMAではメモリ上のデータは分散していた方が良いよね?
・別プロセスなら別ノードにも移せるので自由度が高い
・セキュリティ(他の実行単位からデータが見えない)

等々
629デフォルトの名無しさん:2011/06/28(火) 20:43:17.24
仕事で4Gの空間じゃ足りないってことがあった
64bitならしらねw
630デフォルトの名無しさん:2011/06/28(火) 20:55:56.81
NUMAは違うだろ
どこから割り当てるかは別にプロセス分けなくてもできる
631デフォルトの名無しさん:2011/06/28(火) 21:36:49.16
メモリ空間が共通なのはメリットだろう常考
632デフォルトの名無しさん:2011/06/29(水) 10:48:43.16
プログラムは常に死ぬ可能性がある という前提に立つと、
メモリ空間の共有はデメリットだよな
633デフォルトの名無しさん:2011/06/29(水) 11:36:26.30
メリットもデメリットもある
634デフォルトの名無しさん:2011/06/29(水) 11:51:59.86
>>632
>プログラムは常に死ぬ可能性がある という前提に立つと、
なんという時代遅れのやつ
635デフォルトの名無しさん:2011/06/29(水) 12:05:00.86
スレッド蹴るかプロセス上げるかは、利用場面での損得勘定で決まることだから、
状況想定もなしにメリットデメリットを語ってもナンセンスすぎてなあ…
636デフォルトの名無しさん:2011/06/29(水) 12:54:18.84
>>635
マルチスレッドで得られるメリットは基本的にパフォーマンスのみ。
マルチプロセスで得られるメリットはマルチスレッドで実現不能なことがほとんど。
637デフォルトの名無しさん:2011/06/29(水) 16:52:22.47
ある特徴が長所なのか短所なのかは目的次第(この話に限らない一般論)

パフォーマンスいらないならマルチスレッドなんてしないだろ
638デフォルトの名無しさん:2011/07/23(土) 20:17:54.60
処理中にUIが固まらないようにするためのマルチスレッドは
よく使用されるが、それをパフォーマンス目的とは言わないだろう
639デフォルトの名無しさん:2011/08/02(火) 16:21:14.65
パフォーマンスだけがメリットだとしても、パフォーマンスのメリットは計り知れない
からな
クラしか見てない奴はパフォーマンス需要は頭打ちと思ってるかもしれんが、鯖は逆に
クラウド化でクラの負担も全部引き受ける路線だから、パフォーマンスが非常に厳しく
求められるようになってる訳だし、鯖向けソフトウェアはパフォーマンス一つでシェア
が取れる例も全く珍しくないしな
640デフォルトの名無しさん:2011/08/02(火) 16:23:33.58
×クラウド化で
○クラウド化とか含めて
641デフォルトの名無しさん:2011/08/14(日) 09:56:51.34
>>638
例が適切ではアリマセンネー
UIを固めない = 操作者を待たせない = 操作者も含めたシステム全体のパフォーマンス向上、
という図式が成立するとも言う

パフォーマンス向上以外のマルチスレッド利用としては、
非同期事象を取りこぼさずに受けるため、というのが挙げられると思うが、
それとて取りこぼさずに済むためのハードウェアの速度要件もしくはCPU時間消費の低減につながるため
結果的にパフォーマンス向上と言えなくもないという、
642デフォルトの名無しさん:2011/08/14(日) 12:36:09.51
643デフォルトの名無しさん:2011/08/14(日) 13:42:20.18
>>641
副次的な効果を目的に持ってこないほうがいい。
UIを固めないと中断が実現できたり、操作者のわかりやすさに繋がるんだよ。
それはパフォーマンス向上ではなく、別のことが目的だろう。
644デフォルトの名無しさん:2011/08/14(日) 13:58:19.75
>>643
例えばIDEがエディタを固まらせないでバックグラウンドでソースを解析するのは
>操作者も含めたシステム全体のパフォーマンス向上、
になるんじゃないの?
645デフォルトの名無しさん:2011/08/15(月) 02:52:00.24
>>644
よく読めよ。
>>638が噛みついたのは「処理スレッドをUIと別にするのがパフォーマンス目的か?」
じゃなくて、
「マルチスレッドは必ずパフォーマンスが目的と言えるのか?」だろ。んなこたーない
646デフォルトの名無しさん:2011/08/17(水) 12:42:20.68
>UIを固めないと中断が実現できたり、操作者のわかりやすさに繋がるんだよ。
これをパフォーマンス向上と言ってもおかしくない
http://dic.yahoo.co.jp/dsearch?p=performance&dtype=1
647デフォルトの名無しさん:2011/08/17(水) 18:54:09.83
>>646
どこを読めば良いのでしょうか
648デフォルトの名無しさん:2011/08/17(水) 19:21:06.24
うーん・・
ことプログラミングの文脈に関する限りはユーザーリスポンシビリティやユーザーエクスペリエンス
はパフォーマンスの一部と解釈することはあまり無いんじゃないかな?
649デフォルトの名無しさん:2011/08/17(水) 20:51:02.93
>>646
おかしい
650デフォルトの名無しさん:2011/08/21(日) 09:04:32.75
「パフォーマンスの向上」が何を意味するのか、が決まらないと無意味な議論だな
その点に限れば、主観以外の論拠が出てこない(実際出てない)から、終着点なんか
無いぞ
元々MTのメリットという話題だったが、技術的に何の参考にもならん話だしどうでも
いいんだが
651 ◆0uxK91AxII :2011/08/21(日) 11:45:37.53
意味を定義しても無駄な議論だけどね:b
652デフォルトの名無しさん:2011/09/09(金) 19:42:55.52
C#のマルチスレッドのプログラミングです。

変数がいくつかある。例えばこんな感じ。
int A;
int B;


int Z;
で、スレッド@で定期的にA〜Zの変数の値を更新している。

スレッドAからこれら変数を読みたいのだが、必ずA〜Zまで全部更新された状態で読みたい。
(つまりスレ@が更新処理中に読みに行くのはアウトってこと。)

優先度が高いのはスレ@です。

どうやれば“スマート”なんでしょう?
変数を更新している間スレ@以外の実行を止めるような仕掛けがあるんじゃないかと思って探したんだけど無さそうだね。
653デフォルトの名無しさん:2011/09/09(金) 19:50:28.24
654デフォルトの名無しさん:2011/09/09(金) 20:10:35.64
>>653
それ、なんかちゃうで。
655デフォルトの名無しさん:2011/09/09(金) 21:29:06.03
>>652
途中で読まれてはいけない更新の開始から最後までロックする。
ロックが長時間にわたる可能性がある場合はSystem.Threading.Mutex.WaitOneで
タイムアウトさせる。
656デフォルトの名無しさん:2011/09/09(金) 21:57:27.33
1以外は読むだけなんだろ?
そりゃ System.Threading.ReaderWriterLock だろ
657デフォルトの名無しさん:2011/09/12(月) 00:26:16.03
中途半端な状態で読むのがアウトってだけだったら、一つのクラスにA〜Zの変数をまとめておいて
更新時には丸ごと新しいインスタンスに差し替えてしまえばロックいらないよ
658デフォルトの名無しさん:2011/09/13(火) 18:08:55.63
RCUのめんどいところは古い情報をいつ削除するか
659デフォルトの名無しさん:2011/09/14(水) 18:37:15.35
C#での話だからGC任せでok
あと、インスタンスへの参照を保持する変数にはvolatileを付けとけよ。
660デフォルトの名無しさん:2011/09/14(水) 21:28:32.04
この使い方だと実はつけなくても大丈夫だけどな。
つけとく方がいいけど。
661デフォルトの名無しさん:2011/09/14(水) 22:13:31.15
クライアントが古い方への参照を持ち続けていてはまると予想。
662デフォルトの名無しさん:2011/09/15(木) 00:00:30.87
>661 の他にも、「新インスタンス上の変数A??Zへの書き込み」と
「共有変数を新インスタンスへの参照で更新」がリオーダーされないようにする必要がある。
663デフォルトの名無しさん:2011/09/15(木) 00:24:43.65
.NET Framework 2.0以降(CLR2.0以降)のメモリモデルでは、
書き込み順をリオーダできないというルールがあるため、それは起こらない。
664デフォルトの名無しさん:2011/09/15(木) 02:03:26.35
>>663
一般の変数に関しては、そんな規定は仕様書の何処にもない。
665デフォルトの名無しさん:2011/09/15(木) 02:49:09.91
は?
666デフォルトの名無しさん:2011/09/15(木) 08:20:18.11
コンパイラが順序通りに書き込んでもCPUがそのように
振る舞うわけねーだろ
667デフォルトの名無しさん:2011/09/15(木) 08:23:43.17
メモリモデルの意味も分かってない馬鹿ばかり。
668デフォルトの名無しさん:2011/09/15(木) 08:45:27.59
>>666
お前はMSの文書ちゃんと読めよ
669デフォルトの名無しさん:2011/09/15(木) 09:34:15.77
ちなみに読み込みは順序換えが許されている。
一般的には読み込み順序の問題でvolatileが必要になるんだが、
今回のような処理では、参照変数より先に参照先を読むことが不可能なため、
volatileがなくても実は問題が発生しない。
もちろん読み込みの挿入が許可されてないってのも重要なんだが。

まあ普通はvolatileつけるでOK。
670デフォルトの名無しさん:2011/09/15(木) 10:44:40.93
>>669
いや、だから読み書きともに順序替えが許されてるんだってば
671デフォルトの名無しさん:2011/09/15(木) 11:08:07.18
>>669
つけなくて大丈夫ってことは無いよ
なにか別のパターンと勘違いしてないか?
672デフォルトの名無しさん:2011/09/15(木) 11:27:46.91
つけなきゃだめってのは、何を見て言ってるの?
CLR2.0のメモリモデルでは書き込み順序換えは許可されてない、
かつ読み込みを複数回に分ける事も許可されてない、
したがって今回のような処理では実質的にvolatileは不要。

このことはMSDNマガジンにも書かれてる内容。
673デフォルトの名無しさん:2011/09/15(木) 11:28:52.30
>>670
書き込み順序換えは出来ないとはっきり書かれてる。
674デフォルトの名無しさん:2011/09/15(木) 11:59:15.21
>>673
どこに?
CLIの仕様書にはどこにもそんなことは書かれてないが。
675デフォルトの名無しさん:2011/09/15(木) 12:01:40.73
>>672
それはあんたがMSDNの記事を誤読してるだけだろ。
676デフォルトの名無しさん:2011/09/15(木) 12:08:07.35
>>674
だから最初からCLR2のメモリモデルではと言っとろうに
677デフォルトの名無しさん:2011/09/15(木) 12:13:29.95
>>675
どこを誤読してるのか明確に指摘してくれ。

ttp://msdn.microsoft.com/ja-jp/magazine/ee532386.aspx
正確には全く同じ話ではないが、結論は同じことになる話が出てる。
まあMSDNマガジンの例の方がより無茶な話も出てるけど。
678デフォルトの名無しさん:2011/09/15(木) 12:18:55.76
C# よく分かんないけど、変数をまとめたクラス

class Vars {
  int a, b, c, ...;
  static Vars instance;
}

があって、更新側

Vars v = new Vars();
v.a = aaa;  // 1
v.b = bbb;  // 2
v.c = ccc;  // 3
...
Vars.instance = v;  // 4

これで 1 〜 3 の順番が入れ替わるのは許せるけど、
1 〜 3 と 4 の順番が入れ替わるのってありなの? まじ???
679678:2011/09/15(木) 12:21:02.84
続き。volatile の必要性については、参照側

int prevA = 0;

while (true) {
  Vars v = Vars.instance;
  if (v.a != prevA) {
    doSomething(v);
    prevA = v.a;
  }
}

とすると、参照側の Vars.instance のアクセスがキャッシュされるから、
Vars.instance は volatile じゃないと駄目ってことでしょ。

Vars.instance を直接アクセスせずに getter を介してれば volatile は不要、かな?
680デフォルトの名無しさん:2011/09/15(木) 12:32:34.08
>>679
不要。
読み取りを削除出来るのは、同一ロケーションからの隣接した読み取りのみ。
よって読み取りが削除されることはない。
681デフォルトの名無しさん:2011/09/15(木) 12:34:46.76
>>678
ECMAのメモリモデルではあり得るが、
CLR2のメモリモデルでは起こらない。
682デフォルトの名無しさん:2011/09/15(木) 12:57:20.42
>>680
おっと、もう少し正確には、読み取りが丸ごと無くなってしまうような事はない。
683デフォルトの名無しさん:2011/09/15(木) 21:05:03.01
どうでもええけどえらそーに言ってたやつらが急に黙りこくってて笑えるぞ
684デフォルトの名無しさん:2011/09/19(月) 02:54:28.89
>>677
それって、Xbox360のXNAとかWindowsPhoneとかでも同じなのかな。
IA-64版のメモリモデルをx86版とほぼ同じになるように修正したのは
ビジネス的な判断としてはアリかもしれんが、
PowerPCやarmでも同じようにするのはオーバーヘッドが大きすぎると思うんだが。
685デフォルトの名無しさん:2011/09/19(月) 10:38:04.13
実行環境(.NET Framework)の話とC#などの言語の話がごっちゃになってる気がする。
.NET Frameworkのモデルでは書き込み順が入れ替わることはないが、
その前のコンパイラの段階で x = 1; y = 2;が逆転することはある。
686デフォルトの名無しさん:2011/09/19(月) 11:50:25.42
ねーよ。
何のために変わるんだよ。
687デフォルトの名無しさん:2011/09/19(月) 16:23:59.39
まあCLRのメモリモデルを頼りにしたければ、MSILで書けってこった。
688デフォルトの名無しさん:2011/09/19(月) 17:16:22.88
メモリモデルに反するコンパイルを行うコンパイラがどこにあんだよ。
689デフォルトの名無しさん:2011/09/19(月) 18:54:18.85
\ここにいるぞ!/
690デフォルトの名無しさん:2011/09/19(月) 19:10:50.21
ヒュー!
691デフォルトの名無しさん:2011/09/19(月) 19:37:52.18
ハンドコンパイラ、自由にコードを作成できる
692デフォルトの名無しさん:2011/09/19(月) 20:11:33.77
最近のコンパイラは最適化もしなくなったのか
693デフォルトの名無しさん:2011/09/19(月) 21:18:28.10
「最適化」を「何でもアリ」と勘違いしているヒトが居る模様
694デフォルトの名無しさん:2011/09/19(月) 21:29:41.61
実際問題、最近のマルチスレッドを前提とした中間言語処理系では、
昔みたいな静的コンパイル時の大胆な最適化は行わない。
というか、実行環境のCPUが想定できないので、あまり意味もない。
695デフォルトの名無しさん:2011/09/19(月) 21:36:40.42
もっとも、可能性で言えばECMA仕様準拠のコンパイラならありえなくはない。
MSのコンパイラならあり得ない。
でも多分、ECMA仕様準拠のコンパイラでもそんなことはやらない気がする。
696デフォルトの名無しさん:2011/09/19(月) 22:14:25.39
それこそ言語仕様次第でしょ。

たとえばCプログラムが、逐次一貫性メモリモデルに沿ったプロセッサで動く実行コードに
コンパイルされるとして、じゃあ何が保証されるかというとCの言語仕様の範囲内でしかない。
書き込み順を入れ替えても、Cコンパイラとしては正しい。
697デフォルトの名無しさん:2011/09/19(月) 23:26:17.69
だから最初から特定の処理系の話だよね。
698デフォルトの名無しさん:2011/09/19(月) 23:29:00.91
そして言語仕様だけでは定義されてない範囲ってものがある。
C言語仕様だけじゃマルチスレッドにおいて何もできない。
699デフォルトの名無しさん:2011/09/20(火) 00:11:35.17
結局、>678の質問の答えはどうなん?

CLRの仕様から答えは決まるのか、
それともC#も仕様で決まるのか?
700デフォルトの名無しさん:2011/09/20(火) 00:14:14.83
>699

>698が言ってる通り、C#の仕様では1-4の実行順序は規定されていない。
よって、リオーダーは起こりうる。
701デフォルトの名無しさん:2011/09/20(火) 00:41:04.58
C/C++の仕様だと、;等のシーケンスポイントの前後での入れ替えは
起こらないことが規定されてるけどな。

機械語の書き込み順が、現れた順番で行われるかどうか、という点には
何も規定されていない。JVMやCLR等はそういう点にも言及されていると。
702デフォルトの名無しさん:2011/09/20(火) 00:55:54.52
それはCプログラムの意味(抽象機械上での振る舞い)定義でしかないよ。
意味が変わらなければ入れ替えは許される。
(そうでないと、ループ不変式移動すらできない)

問題は、Cプログラムの意味定義は実行の流れがひとつという前提でなされていること。
703デフォルトの名無しさん:2011/09/20(火) 00:58:37.26
ついでに機械語命令の実行順は、プロセッサの仕様で規定されている。
もちろん未規定な部分もあるけどね。
704デフォルトの名無しさん:2011/09/20(火) 01:14:32.80
???
705デフォルトの名無しさん:2011/09/20(火) 01:18:24.02
>問題は、Cプログラムの意味定義は実行の流れがひとつという前提でなされていること。
C#の言語仕様では、別スレッド等ではなく突然実行が複数になったり入れ替わったりすることを許しているわけ?

>ついでに機械語命令の実行順は、プロセッサの仕様で規定されている。
CLRでは規定されてないとでも?
706デフォルトの名無しさん:2011/09/20(火) 01:26:01.83
さっきから暴れてる方、

>>698が言ってる通り、C#の仕様では1-4の実行順序は規定されていない。

>意味が変わらなければ入れ替えは許される。

の出展を示してくれませんかね。
それぞれ、C#の言語仕様とCの言語仕様の、どの部分で言及されているのか。
でなければ、ただの脳内妄想と区別がつきませんので。
707デフォルトの名無しさん:2011/09/20(火) 01:48:51.52
その通りだと思うが出典だぞ
708デフォルトの名無しさん:2011/09/20(火) 02:28:18.91
C#言語仕様の範囲では、
C#言語仕様の
3.10 実行順序
および
10.5.3 Volatile フィールド
で規定されてる。
でMSの.NET Frameworkの実装としては、何度か出てるCLRの仕様に則っている。
709デフォルトの名無しさん:2011/09/20(火) 08:38:12.37
コンパイラが実行順序かえたら駄目だろ
710708:2011/09/20(火) 09:28:06.57
念のため、俺は>>700ではない。
711デフォルトの名無しさん:2011/09/20(火) 09:28:42.41
レベルひくっ
712デフォルトの名無しさん:2011/09/20(火) 10:22:38.97
              ○____
              .||      |
              .||  ●   |
              .||      |
              .|| ̄ ̄ ̄ ̄
              .|| 君が代は
          ∧__,,∧|| 千代に八千代に
          ( `・ω・|| さざれ石の巌となりて
          ヽ  つ0  こけのむすまで
           し―-J
713デフォルトの名無しさん:2011/09/23(金) 11:34:40.79
>>708
C#言語仕様もCLRの仕様も、またECMAのCLI仕様においても、
全部「命令のリオーダーが許されるか否か」の視点でしか
記述されてないんだよね。

例えばCLR2.0においては、同一スレッド内の書き込みの順序は
入れ替えられないとされてるようだけど、実行環境がx86であれば
それは単に「コンパイラがプログラムを機械語に落としこむときに
書き込み命令の発行順を入れ替えない」とするだけで実現可能。
x86 CPUのメモリモデルは非常に強いので、アウトオブオーダー実行などによって、
ある書き込みが先行する書き込みより先にglobally visibleになることは認められていない。
714713:2011/09/23(金) 11:35:46.25
でも、PowerPCやarmでは事情が違ってくる。
これらのCPUのメモリモデルはx86よりもずっと緩いので、
単に「コンパイラが書き込みの順序を入れ替えない」とするだけだと、
CPUによるリオーダーによって「他スレッドからは書き込み順が
入れ替わったように見える」ことが起こりうる。
一方で、このようなCPUによるリオーダーまでも防ごうとすると、
ほとんどの書き込み命令の間にメモリバリア命令を挟まなきゃ
ならなくなる。当然、パフォーマンスの低下はとてつもない。

.NETのメモリモデルって、x86のことしか考えてないように見えるんだよね。
JavaやC++11のメモリモデルは、そういう「リオーダー禁止」とかの
直接的視点ではなく、もっとメタなレベルで「ある書き込みが
ある読み込みからはvisibleか否か」を定義してるので、
x86以外のアーキテクチャでも実装しやすくなっている。

今後、マルチコアなWindowsPhoneが出てきたときに
いろいろ酷いことになったりしなきゃいいが。
715デフォルトの名無しさん:2011/09/23(金) 18:44:38.36
実際にitanium版とかあるわけで、実用上なんとかなるレベルだったんじゃないの?
716デフォルトの名無しさん:2011/09/23(金) 18:48:00.72
あとCLIとかのメモリモデルもリオーダはメモリの可視性を含めた話だよ。
キャッシュの影響で、実質的に順序が変わったように見える話とかも出てきてるんだから。
特にECMAの仕様はかなりjavaに近いと思うが。
ていうかほとんどjavaと変わらんような。
717デフォルトの名無しさん:2011/09/23(金) 18:52:07.56
書き込み毎にメモリバリアいるんじゃないかってのは俺も疑問無くはないんだけど、
多くのCPUではこのルールを守るのは大してペナルティはないというのも読んだことがあって、
実際のとこはよく分からない。
718デフォルトの名無しさん:2011/09/23(金) 18:54:03.30
何が言いたいのかわからんなあ
719! 【14m】 【東電 66.0 %】 :2011/09/23(金) 18:58:34.31
ペリフェラルいじるときは
エイエイオー
しまくりだ
720 ◆0uxK91AxII :2011/09/23(金) 20:02:20.23
CLRなんて作らないから、どうでも良い。
721デフォルトの名無しさん:2011/09/23(金) 22:55:12.81
>>715
Itaniumで.NETアプリを動かすのって、基本的には
x86のWindowsサーバー上のアプリをそのまま持っていきたい
ってニーズがほとんどだろうから、その場合はパフォーマンスより先に
互換性確保のほうが最大限に重視されるだろうね。
722デフォルトの名無しさん:2011/09/24(土) 03:15:05.37
C++0xとCLRとJavaのメモリモデルの違いとか考えたこともない話だわ
マルチスレッドに詳しいひとは普段どんな仕事してるんだろ
723デフォルトの名無しさん:2011/09/24(土) 10:21:23.71
排他に必要なメモリバリア類をライブラリだかCLRだかVMだかがやるんじゃないの。
そこを超えて踏み込む(=排他をケチる)とメモリモデルの違いが表面化するとか?

俺の持論:volatileで十分w
724デフォルトの名無しさん:2011/09/24(土) 11:58:45.66
volatileの言語仕様知らないだろw
725デフォルトの名無しさん:2011/09/24(土) 15:39:38.60
volatileを信用してると痛い目合うコンパイラもあるぞ
726デフォルトの名無しさん:2011/09/24(土) 15:56:04.66
会う
727デフォルトの名無しさん:2011/09/24(土) 17:11:35.69
コンパイラからバールのような物が飛んでくるのですね
728デフォルトの名無しさん:2011/09/24(土) 17:55:34.09
perlのようなものか
729デフォルトの名無しさん:2011/09/24(土) 18:18:48.58
>>716
ECMA-335はvolatile変数についてrelease-acquireバリアは要求してるけど、
sequential consistencyは要求してないように見える。12.6.7には
> a conforming implementation is not required to provide a single total ordering
> of volatile writes as seen from all threads of execution.
とも書いてるし。
730729:2011/09/24(土) 18:20:59.69
>>716
だから、ECMA-335において、たとえば以下のようなコードでは
volatile int a = 0;
volatile int b = 0;
Thread1: { a = 1; int r1 = b; }
Thread2: { b = 1; int r2 = a; }
r1 == 0 && r2 == 0 という結果も許されるんじゃないかな。
一方で、JavaのvolatileやC++11のstd::atomicはこういう結果を許さない。
731デフォルトの名無しさん:2011/09/24(土) 19:22:11.48
.NETではInterlocked使うんだよ
732デフォルトの名無しさん:2011/09/24(土) 20:10:49.35
メモリバリアとアクセス競合ごっちゃになってないか?
733デフォルトの名無しさん:2011/09/25(日) 00:03:40.81
javaってこれのせいでvolatile遅いんじゃねーの?
734デフォルトの名無しさん:2011/09/25(日) 00:21:16.82
Javaって誕生当初はロックのコストが無視できるくらいVM遅かったの?
コレクションが全部同期とか頭おかしいよね
735デフォルトの名無しさん:2011/09/25(日) 00:25:40.60
遅かった
736デフォルトの名無しさん:2011/09/25(日) 01:33:01.66
複数リクエストが並行してバンバン来るservletやjspがその上で動いてたもんだから大変
737デフォルトの名無しさん:2011/09/25(日) 13:00:47.00
>>734
まさにそのとおり
738デフォルトの名無しさん:2011/10/04(火) 11:57:09.05
ハードディスクが一つしかない環境だと
ファイルアクセススレッドを何本走らせても結局ハードディスクにアクセスしてるのは常に一つだから
二本目以後は意味ないですか?
739デフォルトの名無しさん:2011/10/04(火) 13:08:54.15
そんなことはない。
740デフォルトの名無しさん:2011/10/04(火) 15:42:40.84
シークが増えて、余計に遅くなるという意味なら有る
741デフォルトの名無しさん:2011/10/04(火) 18:03:27.80
CPUから見ればI/Oは超遅いから無意味、と予想するけど
OSやHDDのキャッシュでかなり違うのかもしれない
結局環境依存だしやってみて実測するしかないっていうね
742デフォルトの名無しさん:2011/10/04(火) 20:06:08.63
>>738
>>740
シークを待っている間に別の処理を行える事で、
早くなる可能性もある。どっちに転ぶかは仕様
次第なんで、それだけの話じゃわからない。

確実に言えるのは「早くなる場合と、遅くなる場合と、変わらない場合がある」って事だけだ。
743デフォルトの名無しさん:2011/10/04(火) 20:49:34.91
S-ATAて仕様上はコマンド並び替えとかでシーク減るとか無かったけ?
744デフォルトの名無しさん:2011/10/05(水) 10:48:57.34
期待するだけ空しい
745! 【13.8m】 【東電 78.9 %】 :2011/10/09(日) 21:31:08.21
NCQをまともに機能させるのは大変なことだお( ^ω^)
746デフォルトの名無しさん:2011/10/10(月) 06:46:41.34
FFのリークが酷過ぎ
747デフォルトの名無しさん:2011/10/19(水) 08:42:15.18
メモリバリアとか難しすぎて頭おかしくなりそう

atomic_int a = 0, b = 0;

//thread1
a.store_acquire(1);
int x = b.load_release();

//thread2
b.store_acquire(1);
int y = a.load_release();

これでx == 0 && y == 0が真になることがあるという話なんだけど頭の中でどう考えてもならない
いったいどういうカラクリでx,yが同時に0になるの?
748デフォルトの名無しさん:2011/10/19(水) 09:23:38.50
>>747
正しくはstore_releaseとload_acquireね。
store & acquire とか、load & release とかいう組み合わせはない。
749デフォルトの名無しさん:2011/10/19(水) 13:56:45.85
>>747
他のスレッドに値が反映されるまでラグがあると考えればいいよ
750デフォルトの名無しさん:2011/10/22(土) 16:08:33.08
>>747
atomic_int a = 0, b = 0;
//thread1
a.store_release(1);
int x = b.load_acquire();

//thread2
b.store_release(1);
int y = a.load_acquire();

だとすると、
load_acquire()はstore_release()の前に移動できる。
751デフォルトの名無しさん:2011/10/22(土) 21:42:35.60
そういやなんで皆ロックの速さに拘るの?
スレッド全体の処理量に対してロックが必要なのは極僅かでしょ。
752デフォルトの名無しさん:2011/10/22(土) 21:55:02.53
いやロックの話じゃなくてアトミック操作の話
753デフォルトの名無しさん:2011/10/22(土) 22:55:15.90
排他ロックしたら負け
754デフォルトの名無しさん:2011/10/23(日) 09:19:45.48
volatileで十分w
755デフォルトの名無しさん:2011/10/23(日) 09:26:02.86
>>754
解雇
756デフォルトの名無しさん:2011/10/23(日) 14:57:53.13
volatileでどんなコード吐くかみんとハマるよ
757デフォルトの名無しさん:2011/10/23(日) 15:13:30.40
javaやC#ならvolatileで充分だろうな。
CとC++のvolatileは別もんだから役に立たん。
詳しくはC++11スレを見てこい。
758デフォルトの名無しさん:2011/10/23(日) 15:22:42.74
volatileかmutexかなんてのはこっちでする話だろうに
なんであのスレでしつこく長引いてたんだか
759デフォルトの名無しさん:2011/10/23(日) 16:16:29.85
>>758
言語仕様読まないバカが粘着したせい
760デフォルトの名無しさん:2011/10/23(日) 19:18:18.55
C/C++のvolatileはvolatileで目的があって用意されたものだがマルチスレッドと直接関係はない低水準機能で、
使う場合もあれば使わない場合もあると。
volatile std::atomic<T>はJavaのvolatileとほぼ同じ意味だそうだが。
761デフォルトの名無しさん:2011/10/23(日) 19:28:17.70
コンパイラによる静的な省略や並び替えは抑制できるけど
CPUが実行時に行う最適化には関与しないから無意味
762デフォルトの名無しさん:2011/10/23(日) 21:37:00.66
はあ?
763デフォルトの名無しさん:2011/10/23(日) 21:58:56.17
>>762
少しは勉強しろ
764デフォルトの名無しさん:2011/10/23(日) 22:06:44.84
>>750
atomic_int a = 0, b = 0;

//thread1
a.store_release(1);
int v = a.load_acquire();
int x = b.load_acquire();

//thread2
b.store_release(1);
int w = b.load_acquire();
int y = a.load_acquire();

のときでも x == 0 && y == 0 はありうる?
765デフォルトの名無しさん:2011/10/23(日) 22:06:59.86
意味不明なこと言ってるのがわかってないの?
766デフォルトの名無しさん:2011/10/23(日) 22:07:49.18
>>765
自己レス?
767デフォルトの名無しさん:2011/10/23(日) 22:09:36.03
>>764
//thread1
int v = a.load_acquire();
int x = b.load_acquire();
a.store_release(1);

//thread2
int w = b.load_acquire();
int y = a.load_acquire();
b.store_release(1);

リオーダーされてこうなったら全部0
768デフォルトの名無しさん:2011/10/23(日) 22:11:32.64
>>767
てきとーなこと書くなよ
769768:2011/10/23(日) 22:24:48.00
>>767
すまん勘違いしてた。同じa同士のloadとstoreはひっくり返るはずが無いと思ったが実際の動作ならそうなりえるよね。
770デフォルトの名無しさん:2011/10/23(日) 23:05:40.90
>>760
それvolatile無くてもJavaのvolatileと同じ。
volatile変数としてatomicを使えるようになってるだけで、
特別扱いはない。
771デフォルトの名無しさん:2011/10/23(日) 23:19:22.09
>>767,769
同じスレッド上でのリオーダーの話と別のスレッドから見たときの順序の話がごちゃ混ぜになってないか?

a.store_release(1);
int v = a.load_acquire();//a.store_releaseとa.load_acquireは同じオブジェクトなのでリオーダーできない。
int x = b.load_acquire();//その結果b.load_acquireも上に移動できない。

しかしながらseq_cstじゃ無いので他のスレッドから見たときの順序が保障されないので x == 0 && y == 0 はありうる

これでいいんじゃね?
772デフォルトの名無しさん:2011/10/23(日) 23:32:07.62
そのコードで会話が成立してるところが凄いかも
773デフォルトの名無しさん:2011/10/24(月) 00:06:26.80
いまから一生懸命C++11での質問してる人がいるけど、
まともに使えるコンパイラでてんの?
メモリバリアとかよくわかんないなら、
今使えるライブラリを動かして勉強した方が早いんとちゃう?
3年後11に本腰入れたって出遅れはしないだろ。
774デフォルトの名無しさん:2011/10/24(月) 00:09:00.47
3年後には次の規格が出てるよ
775デフォルトの名無しさん:2011/10/24(月) 00:19:19.45
>>738
なみの処理じゃ、IOの影響がでかすぎて、
速度の優劣はIO次第になるな。
例えば、1600個の画像からMD5を採ったとき、
IO状態次第で0.7秒から、1分40秒もの差がでる。
恐らく前者はキャッシュ効果だろう。
スレッドを4本でスレッドプール使って計算したが、
確かに計算は速いものの、結局IOがもたつくとどうしようもなく遅い。
776デフォルトの名無しさん:2011/10/24(月) 00:20:20.50
>>774
03から11の間に規格あったっけ?
777デフォルトの名無しさん:2011/10/25(火) 11:21:35.66
【OS】 WindowsXP SP3
【言語】 c++
【実行環境】VC++ 2010 + boost
【その他特記する事項】-
以下に示す2パターンの記述で、どっちでもイイヨ…、どちらが良い、どちらもダメで他の方法が良いか、ご指導お願いします。

マルチスレッド処理するクラス(以下、クラスA)をつくっています。
以下のスレッドを生成します。
 ・ネットワーク経由でデータを受信する
 ・受信したデータを内部で加工する
 ・加工したデータを画面に表示する

スレッドを実行する方法について考えています。
{
 クラスAのインスタンスaを作成
 aとスレッド関数名を指定してスレッド生成・開始×3
 join
}
とするか
{
 クラスAのインスタンスを生成して
  コンストラクタ内でスレッドを生成・開始
}// デストラクタ内でjoin
とするか迷っています。
普通は前者のようにする気がします。
後者にすると、一見スレッドが生成されていることに気がつきません。

ですが、クラス・インスタンスの独立性的なもので考えると後者でも良いような気がしました。
が、結局、デストラクタでjoinすることで、
元のスレッドが、a配下のスレッドの終了を待機してしまう、という訳のわからなさがあります。

以上、よろしくお願いします。
778デフォルトの名無しさん:2011/10/25(火) 11:37:57.33
どうでもいいよ
どっちみちそんな手軽にあちこちで無意識に使うもんじゃないでしょ
779デフォルトの名無しさん:2011/10/25(火) 11:46:17.15
デストラクタでJoin失敗したらどうすんの
780デフォルトの名無しさん:2011/10/25(火) 12:39:33.84
スレッドがどうとかより機能別に関数を作れ
781777:2011/10/25(火) 12:55:15.17
レスどうもです。

>どうでもいいよ
作法とかあったらしりたいなぁ、と思いました。(マルチスレッド自体はじめてで。)
今回は簡単なツールなので確かにどうでもいいのですが…。

>Join失敗したらどうすんの
失敗するのですか?
戻り値がvoidだったので気にしてませんでした。
例外が投げられるのかな。調べてみます。
782777:2011/10/25(火) 13:10:39.43
あれ?
結局デストラクタでJoin失敗した場合と、デストラクタじゃない方でJoin失敗した場合とで、どういう違いが起きるのです?

>スレッドがどうとかより機能別に関数を作れ
一つのクラスに押し込めるな、ということでしょうか?
関数は各スレッドで(クラス内で)独立したものを使っていて、
関数間のデータの受け渡しもクラス内のメンバ変数を使っているので、
クラスの使い方的に、理にかなっているかなぁなんて考えたのですが…。
783デフォルトの名無しさん:2011/10/25(火) 14:00:13.83
構造体や変数に volatile とつけたときの
本当の意味を知る方法
784777:2011/10/25(火) 14:47:21.75
レスどうもです。

>構造体や変数に volatile とつけたときの
volatileとか初めて知りました。何てこと…。
でも、コンパイルのコード生成的なオプションで、マルチスレッド指定していれば、変な最適化はされなくないですか?

>どちらもダメで他の方法が良いか
に対するレスですよね?
781か782でしょうか?
785デフォルトの名無しさん:2011/10/25(火) 15:09:03.14
>>777
受信スレッドと加工スレッドと表示スレッドに分けるんだろ。
で、スレッド起動したら基本は動きっぱなしだと理解したんだが。

それなら、受信クラスと加工クラスと表示クラスに分けて、
スレッド起動(受信クラス、ネットワーク情報、受信バッファ)
スレッド起動(加工クラス、受信バッファ、表示キュー)
スレッド起動(表示クラス、表示キュー、表示デバイス情報)
こんな感じで起動すればいいんじゃないのかね。
こういう作りにしておけば、例えばメインスレッドで表示をするように変更するのも簡単だ。
786デフォルトの名無しさん:2011/10/25(火) 15:51:18.15
TBB使えば
787777:2011/10/25(火) 17:02:22.59
>受信スレッドと加工スレッドと表示スレッドに分けるんだろ。
>で、スレッド起動したら基本は動きっぱなしだと理解したんだが。
はい。

>こんな感じで起動すればいいんじゃないのかね。
了解です。
変にまとめすぎない方がいい感じなんですね。
「独立して動くスレッド達のだから、メインでは、何もしないのがいいのかなぁとか無駄に凝ってました。

>TBB使えば
それは、どのような意図でです?
boostとそっくりな気がして、どの様にとりあつかえばヨイのか見当がつかないです。
788777:2011/10/25(火) 17:13:53.40
detach()というメソッドが何を目的にしているのかいまいち理解できないので教えて欲しいです。

>>785 を利用させてもらうと、boost::threadを使う場合(thread_groupで無い場合)
 boost::thread スレッド起動1(受信スレッド関数名、受信クラス、ネットワーク情報、受信バッファ)
 boost::thread スレッド起動2(加工スレッド関数名、加工クラス、受信バッファ、表示キュー)
 boost::thread スレッド起動3(表示スレッド関数名、表示クラス、表示キュー、表示デバイス情報)
で、スレッドを起動しますが、
「あとは、エラー出ても、例外投げても、私は知らないから勝手にやってね。」という場合は、
 スレッド起動1.detach(); スレッド起動2.detach(); スレッド起動3.detach();
と書いてしまっていいんですか?
join()しないと、メモリ的に何かおかしいことになりそうな気がして、ドキュメントを探しているのですが、捗っていないです。

デタッチ自体初めて知った概念なので、理解がすすまないです。
デタッチ:デバッガなどが監視・制御の対象としていた(アタッチしていた)実行中のプログラム(プロセス)を監視下から外すことを「デタッチする」という。

というのは、わかったのですが、自動変数である「スレッド起動x」は、メイン終了で開放されるのではないのですか?
789デフォルトの名無しさん:2011/10/26(水) 12:59:59.34
>>788
pthread_detachとCloseHandleをスレッドに対して
実行した場合を調べてみ。
790デフォルトの名無しさん:2011/11/03(木) 18:34:53.11
visual c++ 2010 Express
についてくる、
Concurrency::concurrent_queue
を使って、
要素にstringを含んだ構造体(そういえばstringだけって試してないな)を取り扱うと、
デストラクタで開放するときに、アクセス違反が起きるんですけどどうすればいいですか?

という質問をしたいのですけど、Visual C++を教えるスレッドへ行ったほうがいいです?
とりあえず、英語圏で同じ問題を出している人をみつけたんですけど、みたいな状態で、アロケータ?なんだそりゃ?な状態なのです。とりあえず英語読んできます。
ageて申し訳ない。
791790:2011/11/03(木) 18:39:17.13
申し訳ないです。

よく考えたら、Concurrency::concurrent_queueとマルチスレッドって関係浅いですね。
他で訊きなおします。
失礼しました。
792デフォルトの名無しさん:2011/11/03(木) 20:00:51.82
そういえばppl.hのメモリリークのバグっていつの間にかなおってたな
793デフォルトの名無しさん:2011/11/15(火) 10:54:58.38
p://ideone.com/CZz2M

Concurrency::parallel_forを使っているかたはいらっしゃらないでしょうか。

画像処理のシミュレータをVC2008Expで書いていて
CreateThreadによる手書きマルチスレッドからOpenMPと移行し
速度的に変わっていないことを確認したのですが
VC2010Expに移行し、OpenMPの導入方法がわからなかったので
parallel_forに書き換えてみた所、異常に遅いのです。

プロジェクトの設定は、2008はリリースデフォルト+OpenMPサポート
2010はリリースデフォルトです。

何か設定を間違っているのかと思うのですが、どなたかわかりませんか?

【OS】XP sp3 32bit
【言語】VC++ 2008/2010 Express
【実行環境】 Core 2 Extreme X9650 3.45Ghzくらい
794デフォルトの名無しさん:2011/11/15(火) 11:43:33.72
プログラミング初心者で課題が出たんですけど…
教えて頂けるとありがたいですm(__)m

・九九の表をVisual Basicで完成させる

・1から100までの整数の和を求める

お願いします
795デフォルトの名無しさん:2011/11/15(火) 13:40:05.39
>>794
スレ違い。

BASICの宿題はお前にまかせた
ttp://hibari.2ch.net/test/read.cgi/tech/1136788500/
796デフォルトの名無しさん:2011/11/15(火) 18:00:31.85
マルチスレッドで九九表を作るという課題かもしれない
797デフォルトの名無しさん:2011/11/15(火) 18:18:03.92
処理そのもののコストよりもスレッド作るコストの方がでがいわw
798デフォルトの名無しさん:2011/11/15(火) 19:26:55.17
>>797
つまり、よりコストを下げるためにFiberを実装する宿題と言うことか。
799デフォルトの名無しさん:2011/11/16(水) 00:04:15.44
教官が採点不能すぐるwww
800デフォルトの名無しさん:2011/11/16(水) 00:07:19.51
SSE使おうぜ
801デフォルトの名無しさん:2011/11/16(水) 08:01:57.58
SSEを使ったからといって、マルチスレッドとはいえないがな。
802デフォルトの名無しさん:2011/11/16(水) 09:10:50.87
数値計算ならSSEとマルチスレッドを両方使うのが常識だな
803デフォルトの名無しさん:2011/11/16(水) 13:08:03.64
ならGPGPUで
804デフォルトの名無しさん:2011/11/16(水) 17:08:36.01
SSE+マルチスレッドなら九九ならず9999999×9999999くらいの表を作るべきだな
805デフォルトの名無しさん:2011/11/16(水) 17:35:23.60
約100T個
806デフォルトの名無しさん:2011/11/16(水) 20:09:53.33
GPGPUってマルチスレッドなのか?
一応処理単位をスレッドと呼ぶけどそれじゃSSEもマルチスレッドになるような
数値計算だとデータ並列が基本だから数値計算プログラムを書く人から見たら
いわゆるマルチスレッドと大して違わないんだろうが
807デフォルトの名無しさん:2011/11/16(水) 20:32:03.35
GPGPUもSSEも「並列化プログラミング」だよね
ただそれらはスレッド無しでも使える技術だから、このスレでは微妙かも
以前は並列処理スレがあったけど、そちらはdat落ちした
808デフォルトの名無しさん:2011/11/16(水) 22:50:07.24
SSEはSIMDだろ、んでGPGPUとスレッドはMIMD。
SSEとGPGPUは機能としては勿論、分類としても全然違うと思うぞ。
809デフォルトの名無しさん:2011/11/17(木) 02:40:46.84
GPGPUで重要な性質はSIMDだろ
いかにSIMDを生かせるかで性能が決まって、アルゴリズムもそれが前提になる
810デフォルトの名無しさん:2011/11/17(木) 02:59:04.56
GPGPUの各クラスタというか構成単位について見ると
同時に異なる命令を実行していることがあり得るので
Single Instructionではない

フリンの分類に当てはめるならMIMD
しかし、もっと狭めたSPMDっていう表現のほうが適切じゃないの
811デフォルトの名無しさん:2011/11/17(木) 03:21:03.30
複数の別々の画像に対して同じ処理を並列に独立に実行したら
タスク並列かデータ並列かどっちになるの?
812デフォルトの名無しさん:2011/11/17(木) 07:24:31.73
どっちも使ってるで良いだろ
813デフォルトの名無しさん:2011/11/20(日) 20:50:45.10
GPUは投機実行するか、単に並列実行するかで方向性がかなり変わるよね。
もっとも、GPGPUとしては投機実行の方が需要が多いだろうけど。
投機実行となると実行してる命令はクラスタ毎に異なるから
やっぱMIMDとしての使用がメインという事でないか。
814デフォルトの名無しさん:2011/11/20(日) 23:03:59.97
GPGPUは「ゆかいな牧場」のメロディーで発音したくなる。
815デフォルトの名無しさん:2011/11/21(月) 00:44:45.34
>>814
しまった、そう発音していた。
816デフォルトの名無しさん:2011/11/21(月) 18:45:55.58
>>815
おまえがいちろうか、
817デフォルトの名無しさん:2011/11/21(月) 19:42:22.04
大人になってから改めて歌詞を見ると下ネタにしか見えないな
818デフォルトの名無しさん:2011/11/22(火) 19:52:25.40
シングルスレッ〜ドでコード おまえ書いてたころ〜
819デフォルトの名無しさん:2011/11/22(火) 20:32:28.94
人というのは知っている言葉を敏感に聞きとれるようになっている
すなわち、それは>>817がエロくなっただけのこと
820デフォルトの名無しさん:2011/11/24(木) 06:40:15.25
かゆいな牧場
821デフォルトの名無しさん:2011/11/25(金) 22:40:29.78
atomic_store、stomic_load関数って自分で実装しなくてはならない羽目になったらどうするんですか
WindowsAPIを探してみたんですがよくわかりません
Interlockedシリーズを応用するんでしょうか?
822デフォルトの名無しさん:2011/12/13(火) 03:13:09.01
メモリ競合は、あるスレッドがあるアドレス位置に書き込みを行っている最中に、
別のスレッドがそのアドレス位置に書き込み、もしくは読み込みを行うことで、
そのアドレス位置に中途半端にデータが書き込まれた状態で別のデータが書き込まれる、
あるいは読み込まれることによって起こる、という認識で正しいでしょうか?
その場合、それはビット単位で起こるのでしょうか?

たとえば以下のように、ある変数に2スレッドで書き込み、1スレッド読み込む場合、
変数の値が 0x00, 0xff 以外の値になることはあるでしょうか?
もし変数のサイズがもっと大きければどうでしょう?

// thread0
var = 0x00;

// thread1
var = 0xff;

// thread2
if( var ) ; // ...
823デフォルトの名無しさん:2011/12/13(火) 05:03:20.45
>>822
環境次第。その対象アドレスにあるのが普通のメモリなら、ビット単位と言う事は無いのでその2値以外になることはおそらくない。
824デフォルトの名無しさん:2011/12/13(火) 17:01:56.05
>>822
どのサイズが問題なく読み書きできるかは環境(CPUやVM等)しだい
(intはOKだがdoubleはだめといった感じ)
825デフォルトの名無しさん:2011/12/13(火) 17:32:59.62
>>822
32ビットx86なら4バイトアライメントされたアドレスの4バイトをmovでアトミックに書き込める、
これが8バイトだとmov2回になるので(もっと違う値なら)2値のどちらでもない状態が存在する、とかいうのはある
でも付いて行けなくなるから考えないほうがいいぞ
826デフォルトの名無しさん:2011/12/14(水) 04:35:01.63
>>823-825
ありがとうございます。
とりあえず、メモリを読み書きする電気的な信号などがバッティングして
データが飛んだりハードが壊れたりということはないんですね。
827デフォルトの名無しさん:2011/12/14(水) 06:38:46.37
メモリ競合程度でハード自体が壊れるなら欠陥品と言わざるを得ない
828デフォルトの名無しさん:2011/12/14(水) 08:09:32.50
>>826
その環境が組み込みでメモリマップドI/Oの先にいい加減な回路が繋がっていたりしたら、壊れるかも知れんが。
尤も、そんな回路ならマルチスレッドに関係なく壊しそうだけど。
829デフォルトの名無しさん:2011/12/14(水) 15:52:37.83
そんなハードウェア上で何も組める気がしないぜ
830デフォルトの名無しさん:2011/12/14(水) 16:07:15.72
>>829
しかしそれでも組むのが我々の仕事だ
831デフォルトの名無しさん:2012/01/15(日) 18:00:02.48
物理ディスクとのI/Oコストってデカイじゃん
もしかしたらアーカイブのままメモリに読み込んで、
メモリ中でアーカイブ展開しながら処理した方が
早いんじゃないかとも思うんだが、
検証しやすいサンプルとか無い?

高速展開と、部分抽出が出来れば効果が現れやすいと思う。
832デフォルトの名無しさん:2012/01/15(日) 18:23:45.87
>>831
20年くらい前に、そういうコンセプトのフリーウェアがあったっけな。

とりあえず試してみたら良いだろ。
圧縮率を20%と仮定するなら、100KBのreadにかかる時間と、
80KBのreadにかかる時間差を計測する。
後はオンメモリに置いといて、その時間差ないに解凍できるかだ。

ちなみにディスクの待ち時間の大部分はヘッドのシーク。
データサイズが多少小さくなったところで、得られる時間は少ない。
データが連続している場合、20KB減ったところで1msも短くならないぞ。
833デフォルトの名無しさん:2012/01/15(日) 20:58:51.56
何だ無駄か。読み込みスレッドで随時解凍しながら取り込めば、
ワーカーの処理待ちを減らせるかと思ったのに。
834デフォルトの名無しさん:2012/01/15(日) 22:18:40.46
いや、IO自体のオーバーヘッドは今でもバカにならない。
ネットワーク上のファイルIOもレイテンシがでかい。
いまどき数百MBからGBオーバーのファイルも少なくないんだから、本気でバッファを大きくとるか、コンカレントに処理して欲しい。

アーカイバをいくつか使い比べると何割というレベルの速度差がある。
速い奴はちゃんとそういう所にも気を配ってる。
835デフォルトの名無しさん:2012/01/15(日) 23:21:05.40
そういえば昔、NetWareというサーバOSがあったな
クライアントのローカルHDDをアクセスするよりも
LANでつながったNetWareサーバ上のファイルをアクセスする方が高速だった
古きよき時代
836デフォルトの名無しさん:2012/01/16(月) 01:37:22.73
JavaのFutureとpthread_joinとの違いが、
スレッドプール使えるかどうかぐらいしか解からん。
アレは、pthread_joinとスレッドプール以外じゃ何が違うの?
(オブジェクトと例外返すのは置いといて)
837デフォルトの名無しさん:2012/01/16(月) 01:47:25.07
いやFutureは結果返すためのものだからそれ置いといたらダメだろ
838デフォルトの名無しさん:2012/01/16(月) 02:01:11.36
pthread_joinも結果は返せるからね。
pthread_joinを軽くラップするだけで、
例外を返すのもオブジェクトを返すのも簡単にできちゃう。
結果を返す事だけに注目すると差異としてはあまりに小さいと思うけど。
839デフォルトの名無しさん:2012/01/16(月) 11:48:41.44
>>831
読みきってから処理するのではなく
読みながら処理する
840デフォルトの名無しさん:2012/01/16(月) 13:00:46.78
無圧縮データでディスクIOが、どれくらい
コスト掛かるのか調べてみた。
調べ方は2つスレッドを走らせ、
片方はひたすらカウント、
もう片方はファイル読み込みしながら、
読み込んだバイト数分だけカウント。
どちらもカウント変数をクリティカルセクションで囲んだ。
CPUは2コア。

この条件で実行するとファイル読み込み
してるほうが1/8程度遅かった
遅い遅い言うけどそうでも無いのな。
841デフォルトの名無しさん:2012/01/17(火) 17:41:36.51
キャッシュ読んでるだけじゃないのそれ
842デフォルトの名無しさん:2012/01/17(火) 20:46:09.02
まぁ、NTFSの圧縮ファイルシステム使って早くなるなら、
みんな圧縮してるよね。
843デフォルトの名無しさん:2012/01/18(水) 00:09:55.35
それは一旦全部解答してから読み込むからでしょ
844デフォルトの名無しさん:2012/01/18(水) 15:32:20.55
845デフォルトの名無しさん:2012/01/21(土) 07:08:56.51
2chのログは圧縮フォルダに入れた方が圧倒的に速い
846デフォルトの名無しさん:2012/01/22(日) 10:58:15.73
パソコン側のHDDキャッシュがお馬鹿ってことじゃあ
847デフォルトの名無しさん:2012/01/23(月) 09:41:58.18
>>846
正しいだろ。
848デフォルトの名無しさん:2012/02/21(火) 23:37:31.35
ディスク絡みのスレッドの話だけど、HDDのランダムアクセスの遅さに驚愕した。

任意のスレッド数(プール使用)で、複数同時にファイルを読み込み、
MD5ハッシュを取り出してファイル比較するツールを作った。
んで、1ファイル1MB未満のファイル群と、1ファイル40MBを超える
ファイル群に対して実行してみた。4コア環境で実行したら
1MB未満だと3スレッドが最速。40MB以上だと1スレッドが最速ってな結果になった。
40MB以上で、1スレッドだとディスクアクセスが100MB/sを超える。
40MB以上で、4スレッドだとディスクアクセスは30MB/s未満まで低下した。

みんなは、この辺どう回避してんの?
849デフォルトの名無しさん:2012/02/21(火) 23:46:23.99
>>848
非同期IOとか、メモリマップドファイルとか。

複数スレッドから同時アクセスなんかしたら、ディスクシークが増えて、
帰って遅くなるのは当たり前。
850デフォルトの名無しさん:2012/02/21(火) 23:47:16.21
>>848
NCQにまかせて神に祈る


ってのは冗談で
1. 読む順番が決まっているならデータをデフラグでその順番に並べておく
2. その順番に読めるように1スレッドで読みに行く
851デフォルトの名無しさん:2012/02/22(水) 00:02:11.03
>>849
理屈じゃ分かっちゃいたんだけどねぇ。まさかここまで遅いとは・・・。

>>850
並列化は諦めるしかないのかねぇ。
852デフォルトの名無しさん:2012/02/22(水) 00:31:00.86
ファイルを読むスレッド(1つだけ)とMD5の計算他をするスレッドを分けるとか?
CPU時間がどっちかに偏ってたらだめかもしれませんが。
853852:2012/02/22(水) 00:34:57.35
って850さんが既に言ってますね。ファイルを読むスレッド1+それ以外の計算をするスレッド複数。
そしてディスクアクセスの時間>>計算の時間なら、ディスクが物理的に1つしかない以上は並列化は無理かと。
854デフォルトの名無しさん:2012/02/22(水) 00:49:03.05
>>852
それが微妙なんだよね。
MD5の計算って一般的に順序依存があるから、
1つ前に計算した計算結果が無いと、
次の計算が始められないんだよ。
そんなんもんで、ファイル別なら順序依存が無いから
とりあえず、1スレッド1ファイル処理にしてたんだけど。

実は、ディスクアクセスというよりMD5の
順序依存が一番足引っ張ってんのかもね。

あと、MD5の計算時間だけど読み込みの10倍遅いよ。
855デフォルトの名無しさん:2012/02/22(水) 00:57:48.08
>>854
〜かもね、とかの妄想に付き合うのは疲れるから、調べてから書けよ
856デフォルトの名無しさん:2012/02/22(水) 01:17:35.11
>>855
調べるつってもなぁ。発想の問題じゃない?
これ以上調べられることあるかい?
857デフォルトの名無しさん:2012/02/22(水) 01:18:33.05
頼むから喧嘩はやめてくれよな
858デフォルトの名無しさん:2012/02/22(水) 01:18:41.54
> 順序依存が一番足引っ張ってんのかもね。

を明らかにすればいいじゃない
859デフォルトの名無しさん:2012/02/22(水) 01:24:03.16
>あと、MD5の計算時間だけど読み込みの10倍遅いよ。
あれ?それならいけるんじゃない?

仮に11コアのCPUがあったとして、
1コア目→ディスクから10個のファイルを読み出してメモリに吐く
2〜11コア目→1コア1ファイル分担当で計算
って形で10コアまでスケールするはずだと思うんだけど。コアはスレッドと読み替えてもok。
860デフォルトの名無しさん:2012/02/22(水) 01:33:14.66
>>859
ロード時間L, MD5計算時間Mとすると(L=10M)
馬鹿正直にやったら10(L+M) = 110M
お前のやり方だと10L+M = 101M
どこがスケールしてるんだ?

ついでに2スレッドでも101Mは出ると思う
861デフォルトの名無しさん:2012/02/22(水) 01:34:10.53
>>860
ごめんどっちが遅いのか勘違いした
吊ってくるわ
862デフォルトの名無しさん:2012/02/22(水) 01:39:04.31
>>854
計算が10倍遅いなら、シングルリーダスレッドでも十分にペイする。
ただ、机上で計算すればあんたの実測値なら3並列と4並列に分かれ目がある。
ファイル一件の読み込みを1、比較するってことなんでサイズは全ファイル
ほぼそろってるとして、4対象の場合のそれぞれの最長パスは

1リーダ+4計算スレッド: 4+10 = 14
全部で1スレッド: 1*4+10*4 = 44
4(リーダ+計算)スレッド:1*(100/30)+10 = 13.33 (100MB/sが4スレで30MB/sになったから)

まあ実測すると他のプロセスとかとの兼ね合いでまた変わるだろうけど、
多分安定度で言えばシングルリーダスレッド+N計算スレッドじゃないかなあ。
OSのページキャッシュに乗っている事が期待できる状況ならまた別だけど。
863デフォルトの名無しさん:2012/02/22(水) 01:42:35.74
>>858
ディスクアクセスの改善が無理ならMD5の
順序依存を直すしか無いと言えるんだけど。
もう本当に打つ手がないか意見が聞けないとなんとも。

>>859
確かにね。最終的にはそれが一番効率がいいのかなとも
思うんだけど、ただその方法は計算するファイルは1ファイルまるごと
読み込まないといけないんだよね。
そこがちょっともっといい方法が無いかと引っかかるよ。
864859:2012/02/22(水) 01:45:16.15
861が俺のレスみたいに見えるので一応自己弁護しておこうw
ロード時間L, MD5計算時間Mとすると10L=M
シングルスレッド→10(L+M)=110L
11コアによるマルチスレッド→10L+M=10.1L
とほぼ11倍の性能ということで理屈上スケールはするはずだ、と。もう寝るおやすみ〜
865デフォルトの名無しさん:2012/02/22(水) 01:46:07.56
>>862
机上の計算の計算式がイミフなんだが
866860:2012/02/22(水) 01:47:47.73
>>864
うんごめん
そのとおり
867859:2012/02/22(水) 01:49:07.58
俺のアホー
マルチスレッドは10L+M=20Lだ。効率は50%弱か。今度こそおやすみー
868862:2012/02/22(水) 02:01:42.37
見直すといろいろあれだったので気にしないでw
869 ◆0uxK91AxII :2012/02/22(水) 15:13:40.47
thread一つ、非同期読込と計算を交互に行う。
870デフォルトの名無しさん:2012/02/22(水) 17:09:49.10
読み込み時間がクリティカルなんだから
読み込みスレッドが他の作業をしたらダメなんじゃないの?
871デフォルトの名無しさん:2012/02/22(水) 19:17:39.81
HDD一個に複数からアクセスすれば、パフォーマンス低下するのが当然じゃあ
872デフォルトの名無しさん:2012/02/22(水) 20:04:50.74
SSDなら実測値が結構改善するんかね
大して普及してないから宛にならんけど
873デフォルトの名無しさん:2012/02/23(木) 00:31:39.79
スレッド制御に頭使いすぎてI/Oウエイトによる遅延完全に無視してない?
874デフォルトの名無しさん:2012/02/23(木) 00:40:50.43
>>872
普及はどこから出てきた
875デフォルトの名無しさん:2012/02/23(木) 01:04:22.28
>>874
SSDから。
876デフォルトの名無しさん:2012/02/23(木) 01:07:07.00
いやだから。
SSDがとんだけ普及してるか、は実測値に影響する項なのか?ってことだろ
877デフォルトの名無しさん:2012/02/23(木) 01:23:30.75
普及してるかどうかは実測値には影響しないよ。
SSD上での実測値改善が見られるとありがたいけど、
世の中SSD搭載してないPCも多いから、
SSDだけで速くなるプログラムはよくないよねって話しだし。
878デフォルトの名無しさん:2012/02/23(木) 01:25:38.17
そっちかよ
自分とこの環境で動かすんじゃないのか
879デフォルトの名無しさん:2012/02/23(木) 01:49:14.20
自作のハッシュ計算ツールだけど、MD5計算速度はキャッシュに乗ってる状態だと
3GHz弱のCore2Duo程度のCPUでも300MB/sは超えてるぞ。
計算のが十倍遅いってどういうことだ?
HDDなんて速くても100MB/s題だと思うが…
880デフォルトの名無しさん:2012/02/23(木) 01:57:30.10
スレッド構成を書いてもらわないとなんとも言えないなぁ
単にシングルスレッドなら100MB/s超えるしね
881デフォルトの名無しさん:2012/02/23(木) 01:59:55.78
>>879
読み込み時間を差し引いた計算時間はどれぐらいだったの?
882デフォルトの名無しさん:2012/02/23(木) 02:05:32.93
>>879
300MB/sってのは、MD5の関数なりクラスなりが1秒間に
計算できた情報量という理解であってる?
883デフォルトの名無しさん:2012/02/23(木) 02:07:57.39
読み込みと計算は別スレッドで同時にやってるから正確には分からんな。
まあいろいろ状況によって時間が変わるけど、計算だけなら最速時で400MB/sくらいだった希ガス。
ああもちろん、読み込みやってもキャッシュに乗ってたら最速だとほぼ同じくらいまで行くよ。
884デフォルトの名無しさん:2012/02/23(木) 02:31:42.72
純粋な計算速度が負けるってのは構成が gcc+linux+Phenom X4 1.8Ghz だからなのかねぇ
885デフォルトの名無しさん:2012/02/25(土) 14:26:44.01
ちょっとスレッドとは違うかもしれないんだけど
メッセージキューを設計しています
シグナルハンドラからキューに積みたいんですが
どうしても排他制御ができません
うまい方法はありますでしょうか
886885:2012/02/25(土) 14:28:07.28
自己解決しました
887デフォルトの名無しさん:2012/02/28(火) 00:27:52.96
C# の.NET4.0なんですけど

List<Double> hoge は適当な値が入っているとして

Parallel.For(0,hoge.Count,(val)=>
{
hoge[val] = 0.0;
});

とした場合、常にhogeの中身が全て0.0になりますか?
この処理はLockしなくても大丈夫のような気がするんですが少し心配です。
888デフォルトの名無しさん:2012/02/28(火) 00:38:36.19
MSの今のList<T>の実装では問題ないはずだけど保証されているわけではない
でもそれデリゲート呼び出しのコストがかさむから普通にループ回したほうが速いだろ
並列でやるんなら、4コアなら領域を4分割して中でループ回したほうがいい
889デフォルトの名無しさん:2012/02/28(火) 00:46:40.99
つまり、>>887

Parallel.Invoke(()=>
{
 for(int i = 0;hoge.Count/4;i++)
  {
   hoge[i] = 0.0;
  }
},
()=>
{
   for(int i = hoge.Count/4;(hoge.Count/4)*2;i++)
  {
   hoge[i] = 0.0;
  }
} ・・・(以下略)
とした方が良いということですか?
890デフォルトの名無しさん:2012/02/28(火) 00:47:12.66
訂正
読み取りだけならスレッドセーフだと書いてあるな
891デフォルトの名無しさん:2012/02/29(水) 12:48:47.15
いくつかstatic変数があって、それぞれに書き込み続ける
スレッドを作ったのですが、コンテキストスイッチが発生
しまくってます(2000〜3000/秒)
int a, b, c;
DWORD __stdcall A(void*){ a = ... }
DWORD __stdcall B(void*){ b = ... }
DWORD __stdcall C(void*){ c = ... }
それぞれのスレッドを単独で実行させた場合は、それほど
スイッチしないので、キャッシュ競合が原因なんでしょうか。
それぞれの変数が同じキャッシュラインに乗らないようにするには
どうすれば良いですか?
それともキャッシュは関係ないですか?
VC10です。
892デフォルトの名無しさん:2012/02/29(水) 21:27:49.37
なんでキャッシュでコンテキストスイッチが起こるのよ…
893デフォルトの名無しさん:2012/02/29(水) 22:05:31.00
>>891
コンテキストスイッチは関係ない。

>それぞれの変数が同じキャッシュラインに乗らないようにするには

キャッシュは8〜32バイトぐらいの単位で管理しているから、
適当に無駄なメモリを確保して、それぞれのメモリアドレスが
隣接しないようにすればよい。
894デフォルトの名無しさん:2012/02/29(水) 22:19:38.86
>それぞれのスレッドを単独で実行させた場合
はああ?
895デフォルトの名無しさん:2012/03/01(木) 00:23:04.48
メモリバリアの間違い?
896デフォルトの名無しさん:2012/03/01(木) 00:47:56.20
なんでメモリバリアが出てくんだよ
897デフォルトの名無しさん:2012/03/01(木) 00:55:22.06
コンテキストスイッチみたいなのはCPUを占有すると起こるものなの
無限ループしてパソコンがハングしたらどうするつもりなんだろうね
898デフォルトの名無しさん:2012/03/01(木) 01:28:54.69
1スレッドで実行→コンテキストスイッチが起こらない
3スレッドで実行→コンテキストスイッチが起こりまくる

これのどこが悪いのか俺にはわからないのだがとりあえずCPUはいくつある?
899デフォルトの名無しさん:2012/03/01(木) 08:36:10.06
>>898
cpuは4コアです。

>>897
各ループにSleepは挟んでます。

>>893
無駄なメモリを置いて、キャッシュ対策しようと思います。
また、コンテキストスイッチ数が多いのは、別の原因を探してみます。
900デフォルトの名無しさん:2012/03/01(木) 08:45:24.09
Sleep入れたらそりゃぁ、コンテキストスイッチもするだろうよ。
901デフォルトの名無しさん:2012/03/01(木) 15:54:56.63
コンテキストスイッチさせるのがSleepの目的のひとつだもんよ。
902デフォルトの名無しさん:2012/03/01(木) 16:16:45.26
static変数に書き込み続けるスレッドとか
Sleep挟んでますとか
キャッシュ競合を避けるとか
    何 考 え て る の よ ?
903デフォルトの名無しさん:2012/03/01(木) 16:43:35.12
マルチプロセスほど枯れきっちゃいない技術だから、ということでしょうがあんめぇ
904デフォルトの名無しさん:2012/03/01(木) 17:01:12.69
スレッドとかどう捉えてるんだろうね?
905デフォルトの名無しさん:2012/03/01(木) 19:41:07.35
>Sleep
噴いたわw
906デフォルトの名無しさん:2012/03/01(木) 20:09:58.15
Windowsなんて常時、100スレッド以上動いてるのに。
907 ◆0uxK91AxII :2012/03/01(木) 20:27:46.46
4CPU環境、速い順に
キャッシュラインを別にした3thread
キャッシュラインが同じっぽい3thread
threadを作らずに1thread
908デフォルトの名無しさん:2012/03/01(木) 20:42:09.96
>>907
>キャッシュラインが同じっぽい3thread
>threadを作らずに1thread

このふたつどっちが早いかは環境やプログラムによるだろ。
後者の方が早くなる事もあるよ。
909 ◆0uxK91AxII :2012/03/02(金) 10:33:44.96
環境と粒度に依存。
910デフォルトの名無しさん:2012/03/26(月) 15:59:30.82
メインプロセスと同じ物理コア内のHyperThreading論理コアで実行されている
サブプロセスが、メインプロセスの動作を邪魔しないようにするためのAPI関数は
ありませんか?

例えば、SetProcessAffinityMaskを同じ値にした2つのプロセスは
SetPriorityClassでサブの優先度を下げれば、メインプロセスが
動いているときはサブプロセスはほとんど動作しなくなります。

しかし、SetProcessAffinityMaskを、メインプロセスで1、サブプロセスで2に
した場合、サブプロセスの優先度が低いにもかかわらず、メインプロセスと
CPUリソースを均等に割り振っているようです。

これを防ぐための、SetProcessPriorityに変わるようなAPI関数はありませんか?
911910:2012/03/26(月) 16:18:58.25
superπを2つのフォルダにコピーして1つをメイン、もう1つをサブとする。
メインのPriorityClassをNORMAL、AffinityMaskを1に固定。
サブのPriorityClassとAffinityMaskを変化させたときの、2つのsuperπの
838万桁計算時間を比較。

記号 P サブのPriorityClass, A: サブのAffinityMask: メインの時間/サブの時間
A P NORMAL, A 1: 5:19/5:22
B P BELOW, A 1: 2:57/5:38
C P NORMAL, A 2: 3:31/3:30
D P BELOW, A 2: 3:30/3:30
E P NORMAL, A 4: 2:53/2:47
F P BELOW, A 4: 2:52/2:47

Dのパターンでのタイムを見ると、サブの優先度がメインより低いにもかかわらず
Cのパターンと同じになっています。

この状況でメインのタイムはFと同等で、サブのタイムはBよりは短くなるような、
SetPriorityClassのような関数はありませんか?
912デフォルトの名無しさん:2012/03/26(月) 16:27:27.46
そんなaffinity maskを設定するのが悪い
913 ◆0uxK91AxII :2012/03/26(月) 16:47:02.42
下手の考え休むに似たり。
914910:2012/03/26(月) 16:56:47.14
AffinityMaskを設定したのは、確実に再現させるためです。
実際には設定しなくても、多くのプロセスが動いている場合に
優先度の高いプロセスが、優先度の低いプロセスに阻害される
可能性を排除したいのです。
915デフォルトの名無しさん:2012/03/26(月) 20:42:35.46
そんなπとかどーでもいいもん計算せずに実用的なもんつくれよ。
πなんて20桁でもあれば地球の外周を計算できるぞ。
916デフォルトの名無しさん:2012/03/26(月) 22:29:33.41
>>910
>メインプロセスの動作を邪魔しないようにするためのAPI関数はありませんか?
OSは何?

>Dのパターンでのタイムを見ると、サブの優先度がメインより低いにもかかわらず
>Cのパターンと同じになっています。
もしかしてWindows?
Windowsにはプライオリティブーストなど、CPU占有率の高いプロセスのプライ
オリティを強制的に下げる機能や、アクティブウィンドウを持つプロセスの
プライオリティを強制的に上げる機能があるから、設定した通りのプライオリティ
で動作している事は保証されないよ?
917910:2012/03/27(火) 09:12:32.64
>そんなπとか
superπを作っているのではなく、優先度の制御ソフトを作ろうとしています。
具体的には動画エンコードしながらゲームしているのですが、
core 2のときはエンコーダのプロセス優先度をIDLEかBELOW_NORMALにしておけば
ゲームのフレームレートが落ちることはなかったのですが、
core i7にしたら落ちるようになってしまったのです。
918910:2012/03/27(火) 09:28:22.17
>OSは何?
Windows全般ですが、7固有のAPIでもかまいません。

PriorityBoostで優先度が動的に上下するのは知っています。
BのパターンのメインプロセスはE/Fに比べて
若干時間が長くなっており、これがPriorityBoostなどによる
効果だと思いますが、これくらいは問題としていません。
919デフォルトの名無しさん:2012/03/27(火) 09:36:39.40
>>917
動画エンコードプロセスに対して、Battle Encoder Shirase みたいな制御をするとか?
920デフォルトの名無しさん:2012/03/27(火) 10:12:01.02
>優先度の高いプロセスが、優先度の低いプロセスに阻害される
HTに係るCPUの内部状態を、そのCPU上で動いているプロセスから、
ソフト的に制御する方法なんて無いよ。
ICEでも使って外部からコントロールするなら兎も角。
・・・っていうか、そのアプローチは不可能に近いって何となくわからない?

>Cのパターンと同じになっています。
ソフト(OS)から見たら、HTなんて関係ないし、二つのCPUは等価なのだから、
ソフトにスケジューリングを任せてたら、
二つのスレッドの実行時間がほぼ同じになるのは当然。

>>917
>core i7にしたら落ちるようになってしまったのです。
それホントにCPU依存の話か?
Core2とi7はソケット形状が違うので、CPU以外にも色々と構成が違うはずだが。
VIAとかの互換CPUならともかく、インテル純正CPUでその手の話って聞かないからさ。

もしかしてCore i7のCPU内蔵GPUを殺すと意図したとおりに動いたりとかしないか?
だとしたらGPUとCPUでメモリバス食いあってるか、GPUのハードウェアエンコーダが
有効になってて、GPU食いあってるだけだと思うぞ。
921910:2012/03/27(火) 10:53:19.74
>919 このソフトを試してみたいと思います。
これでうまくいくようなら、メインプロセスと同じ物理コアの別論理コアで
動くスレッドに対して同じような処理をするプログラムを作ってみようと思います。

>920 ハード的に制御してくれるAPIがないか知りたかったのです。
エンコーダはマルチスレッドですが、GPUは使っていません。
ゲームとエンコーダをE/Fのパターンのように違う物理コアのAffinityMaskにしてしまえば
ゲームのフレームレートが落ちないことは確認しました。
>>911
その計算時間どういう操作してどう計ったの?
838万ケタを同時に計算開始しただけ?

論理CPUの割り当てが別なら優先度なんて関係ないに決まってるんだが、意味分かってるか?
ゲームメインを物理コアにだけマスク指定したら問題なさそうな気がするが、それじゃうまくいかないか?
923910:2012/04/02(月) 12:23:22.30
計算時間はsuperπが計測しています。
同時に計算開始しました。
2つの開始ボタンを押す間の数百ミリ秒は、今回は無視です。

>論理CPUの割り当てが〜
だから、それを優先付けるAPIはないかという質問です。
HyperThreadingを使用するとパフォーマンスが落ちると問題視され
Pentium4からずいぶん時間がたったので、そろそろ出ていないかと思いました。
ないので代替案を提示してくださってるのだと思いますが。

>ゲームメインを物理〜
それだと、論理コアが1つ遊んでしまいます。
遊べば他方を圧迫しない、働けば圧迫する
HTのために2つあるのは状態に関するレジスタ類だけだもの
自分で設定する気が無いんならOSに任せろ
926915:2012/04/02(月) 20:57:35.84
>>923
SetProcessAffinityMask
http://msdn.microsoft.com/ja-jp/library/cc429334.aspx

ムダだろうがこれ使ってみれば?
既出か。メンゴメンゴ。
>>ゲームメインを物理〜
>それだと、論理コアが1つ遊んでしまいます。

何を言ってるのか分からなくなってきた。
論理コアをあそばせるのがもったいないほどCPUを使い切るマルチスレッド化が出来てるのか?
もうちょっと詳しくどういう動作をさせてるのか、どういうスレッド構成になってるのか書いてくれ。

まさかCPUパワーが余ってるのに論理コアが遊んでるのは許せないとかとち狂ったこと言ってないよな、念のために聞くが。
>>928
どんな理由でもかまわないだろ・・・
結局のところ>>924でどうにもならないんじゃないの?
元の質問に誰も答えないのは、万が一あったりするとアレだからだろうねぇ。
でも、さすがに無いと思うよ、そんなAPIは。

別な方法で妥協するしかないんじゃないかな。
あるか否かは、CPUのニーモニックコードのリストを見ればわかるよ。
そこに命令が用意されていないなら、CPUの内部状態をコントロールしようがない。

非公開命令が用意されている可能性は残るけどな。
結局一緒じゃねーか。
あとそういうニーモニックがあるかどうかじゃ確実には分からんよ。



無いと思うけどね仕組み上から考えても。
なんでハードウェアの話になってしまったのかよくわかんないけど、
OS のスケジューリングの話じゃないの?
こんなのとか。
ttp://kerneltrap.org/node/391

Windows も HT を意識したスケジューリングをしてくれればいいのにね。
そりゃOSレベルじゃ制御してない部分の話だもん。
どころかハードレベルでも制御不能だろってのが優勢。
>>934
してるよ
http://www.dosv.jp/feature/0912/04.htm
APIでプログラマに公開されてるかは知らんが
物理マルチコアにHTなんていらないんじゃないかな
HTをONにすると2000ではひっかかりまくるが、XPではスムーズ。
どうみても対応している。
ただlinuxみたいに同一物理コアの別論理コアに割り当てられたスレッドの優先順位を考慮して
タイムスライスの比率を変えるようなことはしてないね。
別コアなのにタイムスライスって、スレッドを一時停止してるっことなんだが、
Linuxではそんなことしてるのか。逆にコスト高くつくんじゃないのか。
941910:2012/04/04(水) 11:42:02.39
HyperThreadingは空いている演算器を有効に使うためのものなのに
メインで使っている演算器も奪ってしまうのはおかしいと考えており
別のOSでは実際にそれを回避するようにもなっているということで
とりあえず安心しました。
なんというか・・・
同時に動かすから、空いてるのを有効に使えるのよ
そして同時に動かせば他方を圧迫する
圧迫を回避する=片方を止める=空いてるのを使えてない なのよ
>>941
なってねーよ馬鹿かお前は。
あいつは人の話を聞かないからなあ。
何でも都合よく解釈しやがる。
そんな理論武装で大丈夫か?
pthread_rwlockの使い方をおしえて
>>946
その前に聞くが、pthread_mutex_lockの使い方くらいは知っているのか?
pthread_rwlockはそれより厄介だぞ。
http://www.tsoftware.jp/nptl/の図4が理解できないならやめとけ
つーか、本当にrwlockが必要なのか?
948デフォルトの名無しさん:2012/05/11(金) 15:36:21.96
2CoreのCPUなら問題ないのに、
HTをONにするとフリーズしたり不安定になるプログラムって何が原因なんだろう?
949デフォルトの名無しさん:2012/05/11(金) 15:41:22.67
複数のスレッドを使うプログラムだろうから、スレッド間の同期がいい加減なのだろう。
950デフォルトの名無しさん:2012/05/12(土) 01:16:48.20
同時に動くとまずいコードがあるんだろう
951デフォルトの名無しさん:2012/05/12(土) 12:53:15.98
2Coreなら大丈夫というのがおかしい。
952デフォルトの名無しさん:2012/05/12(土) 13:07:54.49
別におかしくないよ。
953デフォルトの名無しさん:2012/05/12(土) 13:38:09.65
いやおかしい。
おかしくないなら、2CoreでOKで、HTだとダメなパターンプリーズ。
954デフォルトの名無しさん:2012/05/12(土) 13:45:24.65
ドライバレベルなら昔あったな。
省電力でCPUクロックダウン/休止させる時にHTなので全部止まっちゃいました(テヘっ)ってのが。
955デフォルトの名無しさん:2012/05/12(土) 13:47:28.79
試してみて動いた=OKだと思ってるなら根本的に勘違いしてる
956デフォルトの名無しさん:2012/05/12(土) 13:51:32.68
>>953
そんなこと考えてる暇あったら、HT時に起こってる問題を正確に掴むべき。
ちょっとしたタイミングの違いで動いたり、動かなかったりなんてのはいくらでもある。
957デフォルトの名無しさん:2012/05/12(土) 13:53:22.20
おまえの勘違い半端ねぇ
958デフォルトの名無しさん:2012/05/12(土) 13:54:19.83
たまたまの話ならどうでもいい。
頭の悪い突っ込みは必要ないから。
959デフォルトの名無しさん:2012/05/12(土) 13:55:56.52
突っ込みはしたものの、
HTだけダメなパターンはなに一つも思いつきませんでした。
ごめんなさい。
960デフォルトの名無しさん:2012/05/12(土) 14:01:26.21
お前に思いつくかどうかなんてどうでも良いんだよ。
961デフォルトの名無しさん:2012/05/12(土) 14:03:59.23
>ちょっとしたタイミングの違いで動いたり、動かなかったりなんてのはいくらでもある。

この原因は二つ。
・同期処理をしていない。
・同期処理が必要な部分を洗い出せていない。

HTがダメで2CoreがOKな理由になってないなぁ。
考える暇がないのか考える頭がないのか。
962デフォルトの名無しさん:2012/05/12(土) 14:06:39.92
相談スレで相談したら自分でやれって言う奴を相手にするな。
ただ煽りたいだけの馬鹿なんだから。
963デフォルトの名無しさん:2012/05/12(土) 14:06:45.64
現に原因不明の不具合を目の前にして、そんな事考えるだけ無駄だと分からないやつは開発向いてない。
964デフォルトの名無しさん:2012/05/12(土) 15:03:57.50
問題の起きるメカニズムを解明するのは興味深いが、
解明したところで自己満足以外に得られるものがないからな
結局きっちり同期するしかないんだし
965デフォルトの名無しさん:2012/05/12(土) 15:05:54.53
二つの処理が30ナノ秒以内に終わらないとタイムアウト
するウンコな処理があって2CPUだと偶然動いたとか。

KUSOなコードに論理性を求めるほうが時間の無駄。
単にHT環境で再現するという明らかな不具合を直せばよろしい。
966デフォルトの名無しさん:2012/05/12(土) 18:26:42.65
Pen4の頃のHTを使っていた時は明らかに普通のデュアルCPUと
タイミングが違ってバグの出方も全然違ったよ

>>965の言っているように運よく再現できる環境があるなら
そこで治せばいいんじゃない
967デフォルトの名無しさん:2012/05/12(土) 20:16:48.32
>>953
1スレッドがループ内でレジスタを使い切るパターンだろ
フリーズまではいかんが、挙動が悪くなる
968デフォルトの名無しさん:2012/05/12(土) 20:37:58.42
自分で2CoreではセーフなのにHTをオンにしたら動かない!って言ってるのに、
「そんなパターンは無い!」とか分裂症ですか?って感じ。
そんなパターンがあるからその現象が発生してるのは明らかなのに。
現実逃避もいい加減にしろよ。
969デフォルトの名無しさん:2012/05/12(土) 21:02:29.35
スペック厨で、自分の最強ハードに問題が有るって事が気に入らないんだろう

目の前で起きてる問題をどう解決するかが問題なんだがオタクは空気がよめないね
970デフォルトの名無しさん:2012/05/12(土) 21:07:20.42
HTをオフにしたら動きました。
971デフォルトの名無しさん:2012/05/12(土) 21:19:10.76
>>953
void threadA(){
while(1);
}

void threadB(){
while(1);
}
972デフォルトの名無しさん:2012/05/13(日) 02:00:44.76
それのどこがHTがダメなんだ?
973デフォルトの名無しさん:2012/05/14(月) 09:08:39.75
>>971
シングルコアならOSがタイムシェアリングして均等に実行してくれる。

マルチコアならOSがそれぞれのコアに割り当てて均等に実行してくれる。

HTだとOSはそれぞれの仮想コアに割り当てて均等に実行しているつもりでも、
片方のスレッドが動いている間、もう片方のスレッドは満足に実行されない。
上のようなBusyLoop場合とくに顕著で、何もしない処理がCPUを占有する事になる。
これを防ぐために何もしないから他の仮想コアに処理を渡してよい事を示す
命令が追加されている。
974デフォルトの名無しさん:2012/05/14(月) 16:30:14.82
htでもだいたい均等に割り振られるが。
975デフォルトの名無しさん:2012/05/14(月) 17:15:11.15
HT非対応なんだろ
976デフォルトの名無しさん:2012/05/18(金) 21:50:52.80
すいません。教えてください。
signalマスクをかけたスレッドの関数内で、popenをコールしてるんですが、ctrl+Cするとポインタ(NULLでないpopenの戻り値)からのfgetsが成功する時としない時があるんですが留意する事って何かありますか?
ちゃんとpthread_joinは出来ているのでマスクには問題無いと思うのですが。
宜しくお願いします。
977デフォルトの名無しさん:2012/05/21(月) 08:21:41.23
>>976
どうやってマスクかけたのか、コードをしめせ
978デフォルトの名無しさん:2012/05/23(水) 22:08:45.39
>>976
そうだな。エラーコードには留意するんだな。
979デフォルトの名無しさん:2012/06/13(水) 20:18:27.62
並列化できるはずのプログラムをコンパイルして,
タスクマネージャーのリソースモニタで見ても,
スレッド数が1にしかなりません,どなたか,解決策を教えてください

【OS】 win 7 pro
【言語】 fortran
【実行環境】 インテルR Visual Fortran コンパイラー 11.1
visual studio 2008
【その他特記する事項】
クラーメルの公式で逆行列を求めるプログラムです.
並列化したい部分は以下の通りです.
nは行列の行数,aはもともとの行列,bは逆行列の成分です.
サブルーチンでは,aの値を読むだけで,変化はさせていないです.
その意味でreal*8,valueにしようとしたら,コンパイラに怒られました.
プロジェクトのプロパティで,
構成プロパティ-fortran-最適化-並列化onにしています.

do i=1,n !-全行に対して
do j=1,n !-全列に対して
call sho_det(n,i,j,a,b(i,j))
enddo
enddo


980デフォルトの名無しさん:2012/06/13(水) 20:20:44.88
>並列化できるはず
並列実行できるようなプログラム書かないと
981デフォルトの名無しさん:2012/06/13(水) 20:28:34.56
>>980
少なくとも,i,jはいかなる順番で計算しても問題ないという意味では,並列実行できるのではないかと考えましたが,
サブルーチン化しては並列実行できないのでしょうか?
982デフォルトの名無しさん:2012/06/13(水) 20:57:41.81
sho_det
に並列実行してくれるしかけがあるの?
983デフォルトの名無しさん:2012/06/13(水) 21:13:24.59
>>982
ありません.
984デフォルトの名無しさん:2012/06/13(水) 21:21:17.01
じゃあ、自力でできるようにするしか
並列処理したから早くなるというもんでもないだろうに
並列処理できるようにする方が難易度高
985デフォルトの名無しさん:2012/06/13(水) 21:34:53.36
>>979
sho_detの中身をくわしく。
特にbへの代入
986デフォルトの名無しさん:2012/06/13(水) 23:14:52.16
なぁなぁ、くらーめるの公式ってことは内部で余因子展開やってるよね?
余因子展開は並列和を行うため、一つの行列式は一個のスレッドで固まってないとだめ(もしくはプリフィクススキャン)なので
call sho_det(n,i,j,a,b(i,j))がどうやら行列の個々の要素ごとに演算を行なっているように見えるので
このループ全体が並列化の対象でない限りはcall sho_det(n,i,j,a,b(i,j))だけがマルチスッドレでもだめなんじゃないの?

みたいなことを素人が書いてみましたがどうですか?^^
987デフォルトの名無しさん:2012/06/13(水) 23:42:06.53
サブルーチン呼び出しは副作用を仮定して並列化不可能とみなす。
最適化を実行速度以上、かつプロシージャ間の最適化有効なら
コンパイラーの気分がいい時にはやるときもある。

とりあえず診断に自動パラレライザーのレポートがあるならそれを付けろ。
988デフォルトの名無しさん:2012/06/14(木) 12:17:59.33
ソースを示した方が早くてわかりやすいと思うので,アップします.
http://www5.puny.jp/uploader/info/upload_id/1669260777
pass:giko

>>987
レポートはこれで合ってますでしょうか?
プロジェクト '20120528_fast_pararell_subroutine'、構成 'Release|x64' の中間ファイルと出力ファイルを削除しています。
コンパイルしています インテル(R) Visual Fortran 11.1.067 [インテル(R) 64]...
ifort /nologo /Qparallel /module:"x64\Release\\" /object:"x64\Release\\"
/libs:static /threads /c /Qvc9 /Qlocation,link,"c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\amd64"
"C:\Users\my_note\Desktop\fortran\20120528_fast_pararell_subroutine\20120528_fast_pararell_subroutine\20120528_fast_pararell_subroutine.f90"
リンクしています...
Link /OUT:"x64\Release\20120528_fast_pararell_subroutine.exe" /INCREMENTAL:NO /NOLOGO /MANIFEST
/MANIFESTFILE:"C:\Users\my_note\Desktop\fortran\20120528_fast_pararell_subroutine\20120528_fast_pararell_subroutine\x64\Release\20120528_fast_pararell_subroutine.exe.intermediate.manifest"
/SUBSYSTEM:CONSOLE /IMPLIB:"C:\Users\my_note\Desktop\fortran\20120528_fast_pararell_subroutine\20120528_fast_pararell_subroutine\x64\Release\20120528_fast_pararell_subroutine.lib" "x64\Release\20120528_fast_pararell_subroutine.obj"
Link: executing 'link'

マニフェストを埋め込んでいます...
mt.exe /nologo /outputresource:"C:\Users\my_note\Desktop\fortran\20120528_fast_pararell_subroutine\20120528_fast_pararell_subroutine\x64\Release\20120528_fast_pararell_subroutine.exe;#1"
/manifest "C:\Users\my_note\Desktop\fortran\20120528_fast_pararell_subroutine\20120528_fast_pararell_subroutine\x64\Release\20120528_fast_pararell_subroutine.exe.intermediate.manifest"

20120528_fast_pararell_subroutine - エラー 0、警告 0
989988:2012/06/14(木) 12:22:04.79
ダウンロードパスはこちらでお願いします.
http://www5.puny.jp/uploader/info/upload_id/1373547809
990デフォルトの名無しさん:2012/06/14(木) 12:40:46.03
ちなみに,サブルーチンに入れる前でも,マルチスレッド化はされませんでした.
i,jのdo内で,コールしている部分にそのままサブルーチンの中身を書いていました.

その際,shoi(),shoj(),k,min_more,sekiなど,
ローカルな変数はすべて配列化して,引数に(i,j)をとり,
コンパイラにはdoの順序が任意であるように伝わるようにしたのですが,
それでもだめでした.

991デフォルトの名無しさん:2012/06/14(木) 16:19:16.54
クラーメルの公式って並列処理できるものなの?
から考えませう
992デフォルトの名無しさん:2012/06/14(木) 20:35:34.26
>>987
(´・∀・`)ヘー単にライブラリ追加するだけのオプションじゃないのか
993デフォルトの名無しさん:2012/06/14(木) 21:58:16.81
>>989
リンク先に該当ファイルがないよ
994デフォルトの名無しさん:2012/06/14(木) 22:30:46.09
>>993
http://www5.puny.jp/uploader/download/1339644104.f90
すみません、アップローダになれないもので。pass:giko

>>991
考えた結果、>>981,990のように、出来ると結論づけました。
間違っているなら、間違っているところを指摘お願いします。
995デフォルトの名無しさん:2012/06/14(木) 23:39:25.06
オプション /Qpar-report3を付けてコンパイルするんだ。

並列化阻害要因が表示されるはず。
996デフォルトの名無しさん:2012/06/14(木) 23:43:12.00
/Qpar_report3だったかも。
997デフォルトの名無しさん:2012/06/15(金) 00:19:49.65
>>994
omp parallel
って、そういう使い方するもんじゃないような、よーしらんけど
998デフォルトの名無しさん:2012/06/15(金) 00:28:51.96
上の続き
単純な2重ループだけだと、スレッド化してくれん

ループが二組以上でデータ等の依存関係がない場合にそれぞれのループをスレッド化してくれる

って、バカなりに解釈したけど
999デフォルトの名無しさん:2012/06/15(金) 00:35:11.94
とりあえずサブルーチン化により並列実行でマズそうな点は解消されてるっぽいが
まぁコンパイラーの /Qparallel じゃ分からないくらいには複雑と思われる。

>>979
> VALUE属性はスカラ仮引数にのみ指定可能です。
ttp://www.nag-j.co.jp/fortran/fortran2003/Fortran2003_8_18.html

そういう意味を明示するなら引数授受特性を書いて
PURE 手続きにしてやると上手くいくかもしれない?
ttp://www.xlsoft.com/jp/products/intel/cvf/docs/vf-html/az/az09_39.htm

pure subroutine sho_det(n,i,j,a,b)
implicit none
  integer, intent(in) :: n,i,j
  real*8, intent(in) :: a(n,n)
  real*8, intent(inout) :: b
略)
1000デフォルトの名無しさん:2012/06/15(金) 00:52:10.81
!!-----------小行列用に,i,jを飛ばした自然数の並びを作成
の部分は最適化できそうだけど、自力で...
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。