1 名前:デフォルトの名無しさん mailto:sage [2009/09/21(月) 17:19:27 ] マルチスレッドプログラミングについて語るスレ ■前スレ マルチスレッドプログラミング相談室 その7 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】 【言語】 【実行環境】 【その他特記する事項】
41 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 00:47:32 ] >>39 ロック変数をCASで変更しようとして失敗したらリトライってのはlock-freeではない。 リンクリストのポインタ変数とかをCASで変更しようとして失敗したらリトライってのはlock-freeである。 ってこと?
42 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 00:53:59 ] >>41 うん
43 名前:35 mailto:sage [2009/09/23(水) 06:49:21 ] >>40 レスありがトン。詳しい解説は、とても助かる。 欲しいのは、待機が可能なwait-free queueの実装クラスです。 この場合には、ConcurrentLinkedQueueでキューを生成し、 nullあるいは例外発生であればスレッドを(たとえばwait操作で)待機させるよう アプリケーション側で実装することになるのでしょうか? スレッドを待機させる方法はwait操作以外にもいろいろあるから、 どの方法を選ぶかはアプリケーションにまかせる、という考え方になります。 wait-free queueの意味が「wait操作そのものが不要なキュー」(>>35 )ではなく、 「wait操作を実装していないキュー」の意味に思えてきました。 こんな感じで合っていますか?
44 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 09:15:31 ] LinkedListを使ってキューを作るならCASを使うのでlock-freeだがwait-freeにならない。 もし読み手をwaitでブロックさせるなら文字通りlock-freeでもwait-freeにもならない。 その場合、書き手はブロックした読み手を起こすためにカーネルの世話になるのでlockが発生するかもしれない。
45 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 11:27:50 ] >>44 > LinkedListを使ってキューを作るならCASを使うのでlock-freeだがwait-freeにならない。 CASを使った wait-free なQueueの実装はあるよ。 java.sun.com/javase/6/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html
47 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 11:41:43 ] 連結リスト使うくらいなら別にmutexでも、と思いかけたが、mutexは格段に重いから そうも言えないか
48 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 11:47:45 ] >>47 > mutexは格段に重いから Win32のmutexが無駄に重いだけ。 最近のOSが用意しているmutexなら、競合がない場合のコストは ロックとアンロックそれぞれで高々CAS一回分程度。
49 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 11:50:23 ] なら連結リストよりmutexの方がいい場面は多そうだな、Windows以外は
50 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 11:50:28 ] Win32のmutexはプロセスレベルじゃなくてシステムレベル? で排他してるから重いのはしょうがないかと・・
51 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 11:54:36 ] >>50 ですな。 というか、一般的に言う "mutex" に相当するものを、 Win32では "Critical Section" と呼んでいるから 混乱を招いているだけなんだけど。
52 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 11:58:17 ] W32はCSもMutexも両方Mutexで特性が違うと考えるのが自然
53 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 12:58:23 ] プロセスレベルで排他するからじゃなくて、 カーネルオブジェクトなのが原因なんじゃね?
54 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 13:24:11 ] 目的がそうだからしょうがない
55 名前:35 mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 13:37:41 ] え lock-free queueは同期にも使えるよね?
57 名前:35 mailto:sage [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が同期に利用できないと 考えているわけではありません。
58 名前:35 mailto:sage [2009/09/23(水) 14:39:25 ] (>>57 に追記) >>57 の「一般的なアプリケーション」というのは、 生産者-消費者モデルで設計された、言い換えるとスレッド間同期が 前提となるマルチスレッドアプリケーションのことを指します。 たとえば>>13 ,14のアプリケーションではスレッド間同期が 必要ありませんから、lock-free queueを使用することができます。 (もちろんwait-free queueも使用できます。)
59 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 17:49:20 ] CASとスピンは違うよ。スピンはロック解除待ちのループ。CASは更新中に割り込まれた場合のリトライ。 lock-freeの待ち時間は、よっぽどの酷い競合が起きたときに発生するにすぎない。一般的なアプリでは問題にならない。 そのような競合が起きるのは設計が悪いと思われる。
60 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 18:05:46 ] >>55 www.ddj.com/hpc-high-performance-computing/208801974 これは? 俺はよく解んないからboost.threadのshared_mutexでmultiple-reader/single-writerやってるよ マルチスレッドは奥が深いなぁ
61 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 18:24:48 ] >>59 > スピンはロック解除待ちのループ。CASは更新中に割り込まれた場合のリトライ。 スピンロックは観察対象がロックオブジェクトで、CAS は操作対象そのもの。 スピンロックは失敗時にはクリティカル領域に居る競合 相手の処理を促進する意味もあって普通ディスパッチす ると思う(悪くすると飢餓状態に陥る)けど、CAS は領 域がそもそも小さいのですぐにリトライして ok ってこと? 相当限定的な使い方しか出来ない気がするなぁ…。「ス レッドの状態を気にしなくて良い」んじゃなくて、気に できないんじゃないの?
62 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 18:29:10 ] >>60 boostのshared_ptrもlock-freeで実装されていなかったっけ? ヘッダ見ると幸せになれるかもね
63 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 19:23:00 ] スピン(に限らず)ロックは、ロックされていたら解放されるまでただ待つしかない ロック保持者が何か処理に手間取って (ページングとか、割り込みとかで) 時間を取られたら、 それに引きずられて後続が全部渋滞してしまう lock freeは、相手がすでに処理に入ってても我関せずで自分も処理に入ってしまい、 相手が何か手間取ってたら自分の方が先にCASを勝ち取り、次の処理に進めるというのが強み 負けた方は残念ながら最初からやり直し、今までやったことが無駄になるが、 今戦ってた相手はもう去ったし、次はたぶん成功するんじゃね? 次々に相手が現れていつまでも負け続けるようなひどい競合状態なら、普通のロックの方が良いらしい 負けたら同じ処理をもう一度やり直さないといけないという無駄がどうしてもあるし
64 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 19:40:40 ] >>63 そういうlock-freeもあるけど、単純にアトミックアクセスだけで済ます場合もlockが 無いならlock-freeって呼ぶし(boost::shared_ptrとかがまさにそれ)、その場合は lock-freeと言ってもバスロックを使ったりしてるからややこしいんだが、要するに、 何があってもデッドロックしないアルゴリズムならlock-free、ということだと思って いるんだが
65 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 19:45:19 ] デッドロックはまたややこしい話になると思うから置いとくとして そういうのはやっぱりwait freeに分類すべきじゃないかな wait freeもlock freeの一種といえばそうなんだけど
66 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 20:01:02 ] lock-free : ロックせずにアクセスできる wait-free : lock-freeの条件を満たしており定数時間で処理が完了する事が保証される だけでそれ以外の要素は各実装による・・・じゃねーの
67 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 21:09:37 ] まぁ>>63 と全然違う仕組みのlock-freeも色々あるよってことで
68 名前:デフォルトの名無しさん mailto:sage [2009/09/23(水) 21:20:14 ] > 何があってもデッドロックしないアルゴリズムならlock-free 俺はこれが一番合点がいった。(dead)lock-free なわけ ね。 …しかし「たまたま動いてたプログラムがより堅実に動 くようになります」っていうのはかなり微妙なメリット な気もする(w
69 名前:35 mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 01:24:47 ] 適当にスリープに落とせばいいんじゃ? カーネルにスケジューリングを任せるより効率は若干落ちるが、高負荷時を見れば lock-freeの恩恵が受けられるから悪くないかと。 スレッド間通信がボトルネックの外にあるなら、好きな方法でいいと思われ。
71 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 01:47:24 ] すみません初歩的な質問で申し訳ないのですが,mutexで排他制御された場合、例えば mutexlock(); A[0] = 0; mutexunlock(); の様な場合、スレッドAはA[0]をアクセスして、スレッドBはA[100]をアクセスするとします。 その場合、スレッドBはスレッドAの処理が終わるまで配列Aにアクセスできないのでしょうか?
72 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 01:50:07 ] >>71 そうなるね
73 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 02:22:05 ] 「の様な場合」なんていう他人に通じない省略しないで、 スレッドBの処理も書けばいいのに
74 名前: ◆0uxK91AxII mailto:sage [2009/09/24(木) 04:50:22 ] >>71 //mutexlock(); A[100] = ~0; //mutexunlock(); :b
75 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 07:34:43 ] >>61 > 相当限定的な使い方しか出来ない気がするなぁ…。 > 「スレッドの状態を気にしなくて良い」んじゃなくて、 > 気にできないんじゃないの? これ書いたの俺だけど、malloc() の内部処理辺りには 使えそうだと思った。それと類似して C++ の new() を オーバーライドしといて予め準備しといたメモリプール から取ってくるとかいうよくある奴。 例としてはそんなのでいいだろか? > 例を要求してた人
77 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 08:25:29 ] >>75 その例の場合は素通り 配列が自動的にアクセス禁止になるわけではない ThreadBもThreadCもmutexをロックしてどこからどこまで保護するのか明確にしなければならない
78 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 09:17:59 ] >>77 ロックする範囲が限定されていれば、 他のスレッドは進行を妨げられずに処理できるのですね。 ありがとうございました。
79 名前:35 mailto:sage [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方式 (続く)
80 名前:35 mailto:sage [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ではない、とする考え方です。 難しい論争で、技術的な課題でもありませんから、私もこれ以上の考察は止めにします。
81 名前:35 mailto:sage [2009/09/24(木) 12:10:08 ] >>70 レスありがとうございます。 >>80 の最後で書いたように、lock-free/wait-freeとスリープとを組み合わせた制御を アプリケーション側で実装することによって「同期」は実現できますね。 # せっかく>>60 がDDJの記事を紹介してくれていたのに、それを読まずに>>69 を # カキコしてたのが、まずかったと反省しています。余計な手間をとらせてごめんなさい。
82 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 12:24:59 ] リング遷移よりはスピンした方がいいとか、ある程度待っても何も来なかったら スリープとか、待機時の特性をアプリケーションがチューニングするやり方に なるのは、ハイパフォーマンス向けだと利点と言えるのでは。 まぁ、リング遷移が気にならない状況ならカーネルに任せていいと思うけど。 とりあえず、スピン待機は立派な同期だよ。CPU使用率をやけに気にしてるけど、 MP向けだとスピンじゃないと話にならないことも多い。
83 名前:35 mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 14:28:13 ] デュアルコアでさえスピンは使うって。 lock-free queueのcalleeが同期の機能を持ってるか、にこだわってるの? callerが同期処理をしなきゃならない、だとしても、lock-freeで同期してることに なると思うけど。そうじゃないなら、シーケンスロックはロックの機能を持たない とかいう変な話になるぞ? つーか、ノンブロッキング同期の一種だぞ、lock-freeもwait-freeも。
85 名前:35 mailto:sage [2009/09/24(木) 14:51:24 ] >>84 同じ「待ち」でも、「排他(ロック)」と「同期」は別のものです。 「排他」による待ちは一時的です。もしもそれが長時間継続するようであれば、 それは「設計が悪い」のです(一般にはバグとして扱う)。 それに対して「同期」の継続時間は不定です。 最も長いケースでは、システム全体が終了するまで「待ち」状態が継続します。 また、共有キューを用いた「同期」を実現するには「排他」も必要です。 ただし、だからといって「排他」だけでは「同期」は実現できません。 「排他(ロック)」と「同期」を区別して、考え直してみてください。 lock-freeには「排他」機能があります。ですから「デュアルコアでさえ スピンを使う」ことはあります。でも、lock-freeを単独で「同期」に 用いるのは現実的ではないと言っています。 というか「できる/できない論争」は止めにしませんか?私はこれで降ります。
86 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 15:05:18 ] > 一般的な多くのケースにおいては、その方式は現実的ではないということです。 ここの認識が勘違いしてると思うけどなぁ。 まぁ降りるならどうぞ。
87 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 16:51:14 ] if(v.empty()){/*待機コード*/} int i=v.pop(); 例えばこれも同期
89 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 16:52:09 ] ifじゃなくてwhileだった
90 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 17:23:43 ] >>88 それって、Queueを使うためにmutexやスピンロック等を使った同期であって、 Queueを使った同期ではないような… もし仮にそのことをQueueを使った同期と言っているのであれば、それとlock-free queueとは 関連性薄くない?(べつにbool値のflagだとしても議論できるし) もしかしてQueueとかもう話題的にあんまり関係なくて、 単純に、スピンロックやmutex等の排他制御、CASはそれぞれどういう時に便利ですか? って議論だったりする?
91 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 17:47:00 ] >>88 empty()とpop()が別だから、複数スレッドだとrace conditionになるね。
92 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 18:03:19 ] どう見てもmutexもスピンロックも使ってないし、empty()じゃなくなった後に empty()がtrueにならないことが保証されてるqueueなら競合もしないよ
93 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 18:08:41 ] お互いに勝手なコンテキストを想定して話すから、会話が成り立ってない。
94 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 18:13:27 ] ・読み手/書き手は単数なのか複数なのか ・一般例なのか状況限定の例なのか ・empty()はロックしないことを保証しているか(lock-freeならしているだろうけど) こういう重要な条件をお互いに伝える気も読み取る気も感じられない。
95 名前:87 mailto:sage [2009/09/24(木) 18:25:37 ] while (v.empty()){} ↑こういうコード(ある状態が真になるまでループする)がスピンロックなのかと思ってた。 >>92 みると違うみたい?
96 名前:としあき mailto:sage [2009/09/24(木) 18:34:00 ] > こういう重要な条件をお互いに伝える気も読み取る気も感じられない。 念
97 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 18:50:40 ] >>95 それロックじゃないでしょ
98 名前:デフォルトの名無しさん mailto:sage [2009/09/24(木) 23:38:03 ] 空気読まずに lock-free C++ vector の論文貼るね。既出ならメンゴ。 ttp://www.research.att.com/~bs/lock-free-vector.pdf 2006 年、Bjarne Stroustrup も噛んでる。なかなか性能いいみたい。
99 名前:35 mailto:sage [2009/09/25(金) 02:21:30 ] >>87 lock-free queueを実装する視点であれば、その認識は間違っていないと思うよ。 >>90 >単純に、スピンロックやmutex等の排他制御、CASはそれぞれどういう時に便利ですか? >って議論だったりする? 自分はlock-free queueを使う立場だから、そういう視点で>>81 まで議論を続けてきました。 で、その後から議論が拗れてしまったわけですね。 何が原因かを考えました。自分は、(共有キューの競合による破壊を防ぐ為の)「排他」制御の為に スピンを「使う」ことは「一般的である」けれど、キューが空の場合に「待つ」、いわゆる 「同期」の為にスピンを「使う」のは(汎用PC/CPUの世界では)「一般的ではない」という立場。 それに対して、いや、キューが空で「待つ」場合にも、スピンを「使う」のは(汎用PC/CPUの 世界であっても)「一般的である」というのが、相手の立場。 ある事柄に対して、それが「一般的である/ではない」という解釈は、一般常識論ですから、 それぞれの立場によって異なるのが当たり前です。そんな両者が納得できる結論を導くのは難しい。 だから、>>85 では、これ以上議論を続けても不毛なので止めることを提案しました。
100 名前:デフォルトの名無しさん mailto:sage [2009/09/25(金) 13:02:48 ] できません ↓ できます ↓ 一般的じゃないからできないようなもんです ↓ ハァ? って流れに見えた
101 名前:デフォルトの名無しさん mailto:sage [2009/09/25(金) 15:30:44 ] 私はこれで降ります ↓ 何が原因かを考えました ↓ 提案しました ワロタ
102 名前:デフォルトの名無しさん mailto:sage [2009/09/26(土) 14:00:48 ] >>87 多分間違っていると思うよ コンテキストスイッチは関係ない。 lock-free なキューのメリットは、lock-free でないキューより (ロックしないから)アクセスの並列性が高まること。 もちろん競合するときには性能が落ちるけど、平均的には 性能向上が期待できる。
103 名前:デフォルトの名無しさん mailto:sage [2009/09/26(土) 20:19:00 ] アクセスの並列性ってどういうこと? それが高いと何がうれしいの?
104 名前: ◆0uxK91AxII mailto:sage [2009/09/26(土) 20:34:29 ] こんなケースで、こういうlock-freeなのを実装したら、 これだけパフォーマンスが向上しました・ ...みたいなのを挙げてみてほしい。 どうでも良いけど、jemallocでも、spinlockしているね。
105 名前:デフォルトの名無しさん mailto:sage [2009/09/26(土) 21:38:58 ] >>103 ロックは重い処理だから、それなしにCAS等の手法で数十ステップで収まるloc-freeは 軽い(逐次実行時間が短い)ってことを言いたいんだろ。 ただ、コンテクストスイッチは関係ないと言い切っちゃうのは、もう......だなw
106 名前:デフォルトの名無しさん mailto:sage [2009/09/26(土) 22:37:25 ] lock-freeの定義が各人の頭の中にしかないから1000までこの話題でも結論は出ない(キリッ
107 名前:デフォルトの名無しさん mailto:sage [2009/09/26(土) 23:05:40 ] まず、スピンロックとlock-freeにおけるCASの違いは スピンロックは、単純に同じ動作(CAS)を再試行する lock-freeの実装では、単純に値を読み直す場合や全ての動作を最初からやり直す場合等いろいろあるが とにかく、「同じ値で再度CASを実行する」ということはしない。 wait-freeは、上記の「CASの再実行」が起こらない、ということだから 言い直せば、retry-freeとでも言えるのかも知れない。
108 名前:デフォルトの名無しさん mailto:sage [2009/09/26(土) 23:10:11 ] あと、上のほうで「CASを使わなくてもメモリバリアがあれば云々」という話があったようだが CASが重いのは、CASに含まれるメモリバリア(バスロック)動作が重いのが理由なのだから CASを無くしたからってメモリバリアが必要なら、たいしてメリットは無くなる。 もし、「メモリバリアも無くしてかつwait-freeな実装が可能」というなら話は別だが。
109 名前:デフォルトの名無しさん mailto:sage [2009/09/27(日) 09:14:18 ] >>103 ちょっと古いけど、 www.ibm.com/developerworks/jp/java/library/j-jtp07233/index.html のスケーラビリティの問題あたりから下の部分はどう?
110 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2009/10/01(木) 09:08:46 ] 見よう見まねでスピンロック実装して動作テストしたら標準のCriticalSectionより劇おそだったのは苦い思い出:プライスレス(´・ω・`)
112 名前:デフォルトの名無しさん mailto:sage [2009/10/01(木) 10:15:16 ] Win32のCriticalSectionの激速の理由は プロセッサを判定して、可能ならばunlockにmovを使ってバスロックを避けているから と俺は勝手に想像している。
113 名前: ◆0uxK91AxII mailto:sage [2009/10/01(木) 18:03:15 ] push/popを必要最低限にして、 適宜pause(rep; nop)を入れれば良いだけ。
114 名前:234 mailto:sage [2009/10/01(木) 20:17:23 ] >>112 コンテキストスイッチが無いときはカーネルに入らずに、単にロックカウントをアップしてるだけだからだよ。
115 名前:デフォルトの名無しさん mailto:sage [2009/10/01(木) 21:48:37 ] >>114 いやそんなの当たり前だし。 「単純なスピンロックより速い(>>111 )」理由が何故か?だよ。論点は。
116 名前:デフォルトの名無しさん mailto:sage [2009/10/01(木) 22:46:40 ] >>115 非コンテキストスイッチング時はアセンブラで10数命令しか実行して無いんだから速いよ。 それに>>111 のコードを見なければなんともいえない。
117 名前:デフォルトの名無しさん mailto:sage [2009/10/01(木) 23:01:29 ] だから、その命令の中に、lock xadd とかの重い命令があるんだよ。
118 名前:デフォルトの名無しさん mailto:sage [2009/10/01(木) 23:10:26 ] コンテキストスイッチが無いから速い、とか アセンブラで10数命令だから、とか 偉そうな態度の割に、底が浅すぎる。
119 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 00:06:49 ] お前も相当えらそうだが。
120 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 00:26:57 ] 無知が知ったかぶって偉そうにしながら恥を晒してるのとは違うみたいだけど。
121 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 00:44:09 ] 間違っているというだけで何が間違っているか書かないやつは大抵ハッタリだわな。
122 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 00:44:47 ] >>121 それ正解。
123 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 00:51:21 ] ほれ、ベンチ用意したぞ。 シングルスレッドで、ロック獲得が必ず成功する場合の数字のみ。 実際はカウンタ持ってるから単純なcmpxchgじゃなくxaddで正負と0を駆使して判定してるだろうし ロックを獲得できなかった場合にブロックに移行する処理もあるだろうけどな。 まあ見難いが、面倒くさかったから TABのインデントは見たい人が自分でやってくれ。
126 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 00:54:44 ] これでもまだ「コンテキストスイッチが」「命令数が」と言いたいなら ご自由にどうぞ。
127 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 00:58:52 ] 乙 しかしお前がどのレス書いたやつで何を主張したいのかがわからん。
128 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 01:03:20 ] 実行してみなきゃ結果の意味するところもわからんからね。 まあ俺は>>112 >>115 >>117 とかだが。 関係ないが、stdcallとか、全然意味なかったな。 全部展開されてるし。 しかも、Enter/Leaveもレジスタにコピーされてレジスタ間接コールになってる。
129 名前:128 mailto:sage [2009/10/02(金) 01:04:01 ] >>123-124 が俺な。
130 名前:128 mailto:sage [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 mailto:sage [2009/10/02(金) 11:18:35 ] spinlockの話題>>111 が、CASにすり変わっている件について。
132 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 12:33:54 ] 「教科書通りのスピンロック」って、普通は xchg (test-and-set)でロックを取って、movでアンロックじゃねーの? それとも最近の教科書は test-and-set より先に compare-and-swap を教えるのかな?
133 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 13:15:17 ] 一般のプロセッサでxchgが1バスサイクルで実行される保証なんて無い。 というより、普通は読みと書きになる。(x86が特殊なだけ) だから、ロックを取得するにはCASが必要。
134 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 13:17:13 ] あ、ごめん TASならば確かにCASである必要は無いね。
135 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 13:22:36 ] だけど、「アンロックがmovが普通」は違う。 理由は 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 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 13:52:10 ] >>135 それはメモリバリアの問題であって、movかCASかは関係ない。 mov命令がreleaseメモリバリア効果を持っていればそれで十分だし、 逆に>110で挙げたようなメモリバリア無しCAS命令では不十分。
137 名前: ◆0uxK91AxII mailto:sage [2009/10/02(金) 13:54:13 ] >>135 それはspinlockを使う側が考慮する問題であって、 作る側は無視して良い。
138 名前: ◆0uxK91AxII mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 14:24:08 ] >>136 それがメモリバリアの問題だっていう、そんなことわかってるよ。 そして、「一般的なmov」はメモリバリアの機能など持っていない事 さらに、「(次に書く)このスレで"一般に"用いられるCASという用語」はメモリバリアを持っているもね。 もちろん、CASというのがメモリバリアとは直接は関係ないってことだって充分知ってるよ。 (そうでなければ、lockなしのcmpxchgなんてもの出すわけ無いだろ) だけどこのスレで一般的にCASと言ったら 「アトミック操作で用いる事が可能なCAS」のことが普通だろうに。
140 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 14:28:11 ] 「一般的なmov」つまり、普通のロード/ストア操作はメモリバリアを持っていないのだから 普通のスピンロックの実装では、アンロック処理に movではなくメモリバリアを持ったTASやCASを使う。 (それらはロック獲得処理の段階で存在が示されている) だから「普通はmovでアンロック」などということは有りえない。
141 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 14:37:59 ] >>140 は「教科書では」ね。
142 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2009/10/02(金) 15:36:13 ] はいはいごめんよ。 全部俺が悪かったよ。
145 名前:デフォルトの名無しさん mailto:sage [2009/10/03(土) 09:36:48 ] ttp://d.hatena.ne.jp/bsdhouse/20090720/1248085754 ここが勉強になった。
146 名前:デフォルトの名無しさん mailto:sage [2009/10/03(土) 10:16:52 ] ちらっと見ただけなんだけど、「volatile つけた変数に排他性は無いよ」 ってことをグダグダ言ってるみたいだけど、そんなの当たり前では? 都市伝説もくそもねーよ
147 名前:デフォルトの名無しさん mailto:sage [2009/10/03(土) 11:06:13 ] acquire/releaseバリヤって、 「そのスレッドでのメモリアクセスについて」限定? ↑のスライドだと前後の命令を・・・となってるけど
148 名前:デフォルトの名無しさん mailto:sage [2009/10/03(土) 11:36:54 ] 当たり前よ っつかどういう意味で聞いてる?
149 名前:デフォルトの名無しさん mailto:sage [2009/10/03(土) 11:37:10 ] 菊池バリヤー!
150 名前:デフォルトの名無しさん mailto:sage [2009/10/03(土) 16:40:11 ] 「バリア」って概念には 「メモリアクセスがコーダーが記述した”順”に実行されることが 保証される」っていう以上のものは含まれていない(例えばインク リメント操作がアトミックになることまでは保証されない)と認識し ているのですが。当たってます? ネットに散らばっている情報にはブレがあると思えるし、正直、 勉強不足ではっきりと分からないところがあるので質問します。
151 名前:デフォルトの名無しさん mailto:sage [2009/10/03(土) 18:09:38 ] >>150 それで正しい。 ちなみに、マルチスレッドの世界には「バリア同期」っていう全然別のものもあるので、 メモリバリアのことは「メモリフェンス」と呼ぶようにした方がいい。
152 名前:デフォルトの名無しさん [2009/10/03(土) 19:15:56 ] >>151 ありがとうございます。頭の中がすっきりしました。
153 名前: ◆0uxK91AxII mailto:sage [2009/10/03(土) 21:22:33 ] どうでも良い事だけど。 spinlockを奪い合った場合、 先に取ろうとした方が取れず、 後から取ろうとした方が取れたとしても、 動作としては正しいんだよね。
154 名前:デフォルトの名無しさん [2009/10/03(土) 21:37:43 ] spinlockはアンフェアだからそれで正しいね。
155 名前:デフォルトの名無しさん mailto:sage [2009/10/03(土) 22:29:57 ] >spinlockはアンフェアだからそれで正しいね。 それは答えになってるのか??
156 名前:デフォルトの名無しさん mailto:sage [2009/10/03(土) 23:21:32 ] 間違いではない=正しい という論理がわからないのか? どうしょうーもねーな
157 名前:デフォルトの名無しさん mailto:sage [2009/10/03(土) 23:32:43 ] 正しいのか?って言ってんじゃなくて 答えになってるのか? って言ってんだけど。
158 名前:デフォルトの名無しさん mailto:sage [2009/10/04(日) 00:51:01 ] 答えにはなっているように見える。「正しいのか?」という問いに「正しい」と答えている。 その答えが正しいのかどうかは別の話。
159 名前:デフォルトの名無しさん mailto:sage [2009/10/04(日) 03:29:21 ] ja.wikipedia.org/wiki/%E3%83%99%E3%83%B3%E5%9B%B3
160 名前:デフォルトの名無しさん mailto:sage [2009/10/05(月) 13:09:01 ] >>155 説明になっているかどうかはともかく 答えにはなっていると思うんだが。
161 名前:デフォルトの名無しさん mailto:sage [2009/10/13(火) 02:20:13 ] 火元の人 やり方が理解できない質問者 俺に分からないならこのスレにも理解できる奴いないんじゃね、とか思っていて、 それが態度にも滲み出ている 煽る人 分かってるつもりだけど分かってないで煽り続ける こいつを見た火元は「やっぱり分かってる奴いないんじゃないか」と思いこむ 住人タイプA 一目で分かるがお前の態度が気に入らないしコード示すのマンドクセ つーかこの説明で分かれボユゲ 住人タイプB みんな何言ってんだかわかんね ちょっと違うけどこのパターンに似てる
162 名前:デフォルトの名無しさん mailto:sage [2009/10/14(水) 09:48:32 ] posix準拠のオーソドックスなやり方しかしない俺にはこのスレは不要なようだ おまえら何言ってるかわかんねぇーしw
163 名前:デフォルトの名無しさん mailto:sage [2009/10/14(水) 10:36:30 ] >>162 自分からPOSIXスレッドとかに関連したネタをふればいいんじゃないかな? まあ正直なところ、ここは相談室スレなんだから、あまりにもハードウェア寄りな専門知識が 必要な話題については、できれば「並列化について語る」スレで熱く語ってくれって感じはしてる。 あっちはハード(マルチプロセッサ/マルチコア)全然オケーなスレなんだから。
164 名前:デフォルトの名無しさん mailto:sage [2009/10/14(水) 13:09:43 ] 単に自分の付いていけないレベルの話題を締め出したいだけに見える
165 名前:デフォルトの名無しさん mailto:sage [2009/10/14(水) 13:35:03 ] ということにしたいだけにも見える
166 名前:デフォルトの名無しさん mailto:sage [2009/10/14(水) 21:17:55 ] つーか俺はposix準拠な世界で生きてきたので。 おまえらよくposix非準拠な話題で盛り上がれるなーw
167 名前:デフォルトの名無しさん mailto:sage [2009/10/14(水) 22:48:54 ] >>166 CASやメモリバリアなどはpthreadライブラリの実装者にとっても 必須の知識だよ。
168 名前:デフォルトの名無しさん mailto:sage [2009/10/14(水) 23:10:22 ] >>167 利用者にとっては?
169 名前:デフォルトの名無しさん mailto:sage [2009/10/15(木) 03:21:14 ] POSIX厨としか言いようがない
170 名前:デフォルトの名無しさん mailto:sage [2009/10/15(木) 08:47:16 ] >>169 POSIX使うのが普通じゃないの?
171 名前:デフォルトの名無しさん mailto:sage [2009/10/15(木) 13:13:35 ] pthreadにはアトミック操作が定義されてないから、 単なるカウンタのインクリメントでも いちいちロックしなきゃならんのが嫌だ。
172 名前:デフォルトの名無しさん mailto:sage [2009/10/16(金) 00:37:47 ] なんでPOSIXで厨なんだよ(´・ω・`)
173 名前:デフォルトの名無しさん mailto:sage [2009/10/16(金) 02:28:34 ] POSIXスレッド以外の話題ってだけで叩くなら完全に厨だろ
174 名前:デフォルトの名無しさん mailto:sage [2009/10/16(金) 06:51:32 ] 他人を厨と決めつける人が厨に見える
175 名前:デフォルトの名無しさん mailto:sage [2009/10/16(金) 08:03:36 ] 何でも鸚鵡返しすれば反論になると思ってるだろ
176 名前:デフォルトの名無しさん mailto:sage [2009/10/16(金) 08:04:58 ] baka
177 名前:デフォルトの名無しさん mailto:sage [2009/10/16(金) 08:09:28 ] pthread地獄 part 2 pc12.2ch.net/test/read.cgi/unix/1166620307/ ここへ行けばいいのに
178 名前:デフォルトの名無しさん mailto:sage [2009/10/17(土) 03:19:26 ] /\ ┌┐ ┌┐ ___ ___ / __ \ /\ ..||.. /\ || ___ \\ \ / / .\ \ \ \ .||. / / ┌──┘└──、\\  ̄  ̄ / / .\ \ \/ .||. \/ └──┐┌─ 、| |__| / / ┌──┐.\ \ ┌───┘└───┐ .|| || ..\/ └┐┌┘ .\/ └───┐┌───┘ / / || ┌┘└┐ /\ .||. /\ / / / / └┐┌┘ / / .||. \ \ / / / / ┌─┘└─┐ \/ ..||.. \/ \/ / / └────┘ └┘ \/ ....、 ....................--------、, i~゙7 r‐ッ !゙゙.! ! ! : !―――;;;;;;''''''''ゝ ,,ノ゛ ._ / ./ .,! .,! ! ! .,..............! ヽ..........-、 | |./ / .l、,`''-./ ./ ! ! | | ――ーッ .iー''''''''i | | l'-‐゛ `゙ッ .ゝ、 .| | | ,! ./ ./ ! ! ../ .,! /.,r'"\,/ .!ー′ ./ .,! . / ./ | │ .,./ ./ ,..‐" / . / / ./../ ./ .l゙ .r'"./ ゝ/゛ : ,,-'゛./ .〈 / .'|,゙,゙,,,, " .`゛ ゙'''"
179 名前:デフォルトの名無しさん mailto:sage [2009/10/20(火) 15:39:31 ] その “全米” はグアム島を含むのでしょうか。
180 名前:デフォルトの名無しさん mailto:sage [2009/10/20(火) 19:08:01 ] グアム、どうなんだろ。州に昇格すればいいのに。まあ、しないだろうけど。
181 名前:デフォルトの名無しさん [2009/11/03(火) 00:02:53 ] スレッドを終了させるときは_endthreadexじゃなく そのままreturnでもいいのか?スタックの開放されない?
182 名前: ◆0uxK91AxII mailto:sage [2009/11/03(火) 00:28:01 ] 良い。 mallocで取ってきた領域をfreeしなくて良いのと同じくらいに。 スタックとやらは、_endthreadexとは無関係。
183 名前:デフォルトの名無しさん mailto:sage [2009/11/03(火) 00:59:57 ] freeしろよ
184 名前:デフォルトの名無しさん mailto:sage [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 mailto:sage [2009/11/03(火) 01:52:01 ] 182は無かった事にしてください。 んゆ。
186 名前:184 mailto:sage [2009/11/03(火) 14:42:55 ] スレッドに強い人に補強して欲しいのだけど、それとも184の認識で問題なし?
187 名前: ◆0uxK91AxII mailto:sage [2009/11/03(火) 17:34:11 ] Microsoft Visual Studio\VC98\CRT\SRC\THREADEX.C んゆ。
188 名前:デフォルトの名無しさん mailto:sage [2009/11/03(火) 17:55:09 ] 問題なし
189 名前:デフォルトの名無しさん [2009/11/03(火) 22:08:15 ] スレッド識別子って何なんだ? 何に使うの?
190 名前:デフォルトの名無しさん mailto:sage [2009/11/03(火) 22:25:48 ] 殺したり、止めたり。
191 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 21:43:06 ] 他スレッドの変数の中身知ることってできないかな?
192 名前:デフォルトの名無しさん mailto:sage [2009/11/04(水) 21:55:11 ] メモリ空間は共有しているので、アドレスがわかれば普通に参照できる。
193 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 12:32:06 ] win32のインターロックをクリティカルセクションと 同じように使ったら早くて驚いた。 両者の内部的な違い・利点・欠点てなんですかね?
194 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 14:06:45 ] そもそも用途が違うんじゃない? インターロックは変数1個ぶんの更新しかできないでしょ? インターロックを使ってクリティカルセクションと同様のものを作ることはできるだろうし、 クリティカルセクションを使ってインターロックと同様のものを作ることもできるだろうけど、 そういう話?
195 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 14:31:15 ] インターロック一発で出来ることならインターロックで。
196 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 14:54:32 ] win32のクリティカルセクションは衝突しなければインターロックと同じくらい早いんだなこれが
197 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 16:01:33 ] いや倍くらいは遅いだろう。
198 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 16:15:02 ] んだ。インターロックで済むならそれが数倍早い。
199 名前:193 mailto:sage [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() { } };
200 名前:193 mailto:sage [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); } };
201 名前:193 mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2009/11/05(木) 20:42:07 ] ソースまともに見てないけど、CSがもしインライン化されないなら性能的には勝てない だろうしなぁ まぁ、asm読めば全て分かるだろうけど
203 名前: ◆0uxK91AxII mailto:sage [2009/11/05(木) 23:23:50 ] TryEnterCriticalSection ~ Sleepだとどうなるの、っと。 threadをCPUと1:1にbindしたらどうなるの、っと。 timesliceを変えたらどうなるの、っと。 結果は書かない方が良い。
204 名前:193 mailto:sage [2009/11/06(金) 07:01:38 ] >TryEnterCriticalSection ~ Sleepだとどうなるの、っと。 これだけやってみた。 上記のテストだとインターロックとの差は0.5秒内、 つまりほとんど差がなくなった
205 名前:デフォルトの名無しさん mailto:sage [2009/11/06(金) 13:00:12 ] プロセッサ数が2以上ならSpinWaitにしたらどうなる? あとインターロックのIncrementでダイレクトアップデートにしたらどうなる?
206 名前: ◆0uxK91AxII mailto:sage [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 mailto:sage [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 mailto:sage [2009/11/06(金) 20:37:44 ] 同じ処理なのに所要時間がブレるとか、 先に開始したthreadよりも、後から開始した方が早く処理を終えるとか。 そういうのが起こりうる。 computer gameでmulti threadの利用に消極的な理由の一つだと思う。
209 名前:193 mailto:sage [2009/11/06(金) 23:12:33 ] >>205 >インターロックのIncrementでダイレクトアップデートにしたらどうなる? 1.3秒だった >SpinWait これC#じゃん
210 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 01:40:37 ] スピン待機はC#限定じゃなく一般的な概念だ
211 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 09:40:03 ] スピンすると余計遅くなりそうだな。 一般的な使用状況に比べて処理と競合がタイトすぎるせいかな多分。
212 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 09:45:49 ] ああつまり3スレッド同時じゃなくて1スレッドで3回繰り返した方が速いとかっていう状態ね。
213 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 17:33:40 ] あーいやいや、これだとちょっと書き方がおかしいな…まあいいや
214 名前:193 mailto:sage [2009/11/07(土) 19:49:07 ] スピンロックは信頼性がないという話を聞いたような。 さて上記のベンチですが、1スレッドで3回繰り返したほうがずっと早いです。 衝突したときに別の処理をせずに待つ場合はシングルスレッドにした方がいいかも。
215 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 20:02:47 ] スピンロックに信頼性が無かったらどうすんだよw 全然仕組みとか分かってなくて使ってる匂いがぷんぷんするな
216 名前:デフォルトの名無しさん mailto:sage [2009/11/07(土) 20:03:53 ] スピンロックとスピンウェイトは基本的に別物です。
217 名前:デフォルトの名無しさん mailto:sage [2009/11/08(日) 00:12:02 ] それと信頼性に何の関係が?
218 名前:デフォルトの名無しさん mailto:sage [2009/11/08(日) 02:55:49 ] スピン待ちの話をされてスピンロックどうこうと返すのがおかしい
219 名前:デフォルトの名無しさん mailto:sage [2009/11/08(日) 10:06:21 ] 上の人じゃないけど、スピンロックはスピンウエイトを使ってやってるかとおもてたよ(´・ω・`)
220 名前: ◆0uxK91AxII mailto:sage [2009/11/08(日) 12:45:22 ] spinlockでlockできる保証は無いね。 偶然上手く動いているだけ。
221 名前:デフォルトの名無しさん mailto:sage [2009/11/09(月) 01:48:53 ] ◆0uxK91AxIIで検索したら、NGしてもいいくらいトンチンカンな奴だな
222 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 14:27:27 ] トリップ付けるような奴だもの。
223 名前:デフォルトの名無しさん mailto:sage [2009/11/10(火) 20:06:21 ] トンチンカンなんて久々に見た おやつあげないわよ
224 名前:デフォルトの名無しさん mailto:sage [2009/11/11(水) 09:14:41 ] 抜作先生の方がまだ新しいな。
225 名前:デフォルトの名無しさん mailto:sage [2009/12/15(火) 00:01:41 ] マルチスレッド対応の基数木のアルゴリズムって どうやって記述すればいいのでしょうか? CかC++で探しています。
226 名前:デフォルトの名無しさん mailto:sage [2009/12/22(火) 22:31:16 ] 読み込みと書き込みが1スレッドずつの場合でもメモリ破壊って起きるのでしょうか? たとえば、ある変数をメインスレッドで読み込み続け、 複数のサブスレッドで、クリティカルセクションを用い、書き込むといった場合です
227 名前:デフォルトの名無しさん mailto:sage [2009/12/22(火) 22:39:31 ] >>226 とりあえず破壊読み出しメモリだと死ぬよね。
228 名前:デフォルトの名無しさん mailto:sage [2009/12/22(火) 23:29:29 ] >>226 まずメモリ破壊を定義してもらおうか
229 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 01:41:11 ] パソコンのネジ外して開けると見えてくるメモリの部分をハンマーで叩く
230 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 01:42:27 ] ハードウェア的な話題もするんか
231 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 02:21:03 ] 宇宙線による確率的なビット反転は防ぎようがない
232 名前:226 mailto:sage [2009/12/23(水) 10:10:00 ] データが飛ぶという意味でのメモリ破壊です ハード的にどのように動作しているのか分からないのですが 同アドレスに同時にアクセスされることによってメモリ破壊が起きるのでしょうか?
233 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 10:20:05 ] 書き込みをクリティカルセクションで同期して、クリティカルセクションを抜けたところで可視性が保証されたとしても、 読む方が書き込み中にその変数を見る可能性があるなら、少なくとも意図しない値を読む可能性はあるんじゃない? (+不変な変数見てると思われるかもね) 要求次第だけど、 この手のポーリングするやつは、次に読めればいいからその瞬間のスナップショットで十分だと思うので、 Atomicな操作用のAPI使うとか、書き込みがAtomicであることが保証されるならvolatileだけでもいいかも。 その変数の読み書きだけ同期とっても、読んでる間の書き込みは防げても、 読み込みが終わってクリティカルセクション抜けたあと、それで処理しようと思ったら もう書き換わってることもあるし。 読んだ値の処理が終わるまで書き込ませないなら、話は別だけど。
234 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 11:15:37 ] 昔使ったタイマ LSI でラッチ→lo-read→hi-readって いう約束ごとのあるやつがあったな。hi-readでラッチ が外れる奴。word-read 命令が使えるかどうかは CPU 次第。
235 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 12:47:17 ] >>226 ハードや操作による。 つーか、まずは「アトミックな操作」という概念をどっかで調べとけ。 例えば、x86のCPUなんかだと、どういう操作がアトミックかはIntelが規定している。 アトミックな書き込みなら、別のコアからの読み込みが割り込む可能性は無い。逆に アトミックでない書き込みなら、例えば半分くらい書き込んだところで別のコアが 読み込む可能性があるということ。 x86なら、厳密な規定はIntelの英語版サイトに落ちてる。32bitアラインドなreadや writeは確実にアトミックだ。相当古いx86以外はキャッシュアラインドなら大丈夫。 read-modify-writeはLOCKプリフィクスが無い限りアトミックではないが、xchg 命令はLOCK#が自動的にアサートされるのでアトミックだ。 まぁ、アセンブラを直接叩くんじゃなければ、イントリンシック命令を調べておけば 十分だが、その裏でどういうCPUの動きをしているかは理解しといた方がいい。 つーか、低水準の話と高水準の話で全然違いすぎるんだよな。俺はどっちの話でも 構わんけど、分けた方がいいのか?
236 名前:226 mailto:sage [2009/12/23(水) 12:53:08 ] ありがとうございます もっと勉強します
237 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 13:31:19 ] >>232 そんな事は起きないようにハードウェアが作られてる 物理的なメモリへのアクセス経路は1個しかないから、同じアドレスに同時にアクセス なんて事は出来ない 命令が書いた順に実行されるかとか、他のコアやスレッド云々は >>235 の通り
238 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 13:31:47 ] クリティカルセクションを用いって書いてあるから、なんとなくWindowsかと思ってた。
239 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 13:32:15 ] >>235 ここはム板だから低水準の話はついていけないと思う
240 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 13:49:38 ] >>237 > 物理的なメモリへのアクセス経路は1個しかないから、同じアドレスに同時にアクセス > なんて事は出来ない いつの時代の人?
241 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 14:00:02 ] >>239 いやそれは無い
242 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 14:00:28 ] ん?今はどこが違うの?
243 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 14:04:04 ] >>235 x86は巨視的には古典的設計だからまだ理解しやすいけど、PPCなんかだとリオーダー とかが剥き出しになってくるからさらにごちゃごちゃするんだよな
244 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 14:06:45 ] そこでeioioですよ!
245 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 14:07:20 ] 間違えた、eieioだった イーアイイーアイオー!
246 名前:デフォルトの名無しさん mailto:sage [2009/12/23(水) 14:28:55 ] エイッエイッオッー
247 名前:デフォルトの名無しさん mailto:sage [2009/12/26(土) 12:32:01 ] この辺の話題が体系的に書かれてる教科書が欲しい
248 名前:デフォルトの名無しさん mailto:sage [2009/12/26(土) 14:41:39 ] 開拓が進行中のジャンルだから、書いたそばから陳腐化しそうでなかなか難しいかも しれないな
249 名前:デフォルトの名無しさん mailto:sage [2009/12/31(木) 15:09:39 ] 何をもって高性能とするかをはっきりさせたいな シングルコア100%アイドル3コアでできることを4コア25%ずつで処理することに意味はあるの?
250 名前:デフォルトの名無しさん mailto:sage [2009/12/31(木) 15:12:36 ] >>249 に追記 並列処理の有利はわかるけど、これからは直列処理も並列化しようとしてるんでしょ そんなの意味ないよねという話
251 名前:デフォルトの名無しさん mailto:sage [2009/12/31(木) 15:50:00 ] 1コア100%3コア0%ってCPUがボトルネックになってんじゃねーの
252 名前:デフォルトの名無しさん mailto:sage [2009/12/31(木) 15:50:26 ] 何を言ってるの?
253 名前:デフォルトの名無しさん mailto:sage [2009/12/31(木) 21:19:08 ] >>249 は軽くエスパーが日本語に翻訳しないと分かりづらい 4スレッドにしたら全部25%になっちゃうような処理までマルチスレッドにする 意味あんの、って言いたいんだろうし、だからCPU屋は2コアや4コアで現状維持 しながら別の進化の方向性を探ってるのも事実 だがそもそも、そういう微妙なケースにまで頑張って適用しようぜMTマンセー、 というようなスレではないので、そんな的外れなこと言われても一瞬何の話だか 分からんし、今更何をとしか言いようがない
254 名前:デフォルトの名無しさん mailto:sage [2009/12/31(木) 21:28:43 ] >>253 日本語でおk
255 名前:デフォルトの名無しさん mailto:sage [2009/12/31(木) 21:35:30 ] >>253 余ってるCPUに仕事振る余地のない処理なら それでいいんじゃね?
256 名前:デフォルトの名無しさん mailto:sage [2009/12/31(木) 21:39:14 ] >>249 の問題提起自体が微妙 アムダールの法則くらいで十分じゃねーの?
257 名前:デフォルトの名無しさん mailto:sage [2010/01/03(日) 18:49:32 ] そもそも並列化できない処理まで並列化しようとしてるなんて話は聞いたこともない。 誰が言ったんだそんなこと。
258 名前:デフォルトの名無しさん mailto:sage [2010/01/03(日) 21:49:55 ] >>249 が言ってるな
259 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2010/01/16(土) 03:18:30 ] >>259 >WindowsにあるWaitFor〜みたいに複数待つ つ developers.sun.com/solaris/articles/event_completion.html
261 名前:デフォルトの名無しさん [2010/01/26(火) 00:12:16 ] スレッドを終了させないままアプリを閉じた場合 やっぱメモリリークとか起きるの?
262 名前:デフォルトの名無しさん mailto:sage [2010/01/26(火) 00:20:29 ] 環境を想定しないとなんともいえない。
263 名前:デフォルトの名無しさん mailto:sage [2010/01/26(火) 00:33:22 ] >>261 OS破壊されるぞ?いいのかそんなことしても
264 名前:デフォルトの名無しさん mailto:sage [2010/01/26(火) 00:49:27 ] >>261 ja.wikipedia.org/wiki/メモリリーク
265 名前:デフォルトの名無しさん mailto:sage [2010/01/26(火) 10:22:10 ] 破壊されるようなOSなんか使うなw
266 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2010/01/26(火) 16:20:40 ] 断る。
269 名前:デフォルトの名無しさん [2010/01/26(火) 16:24:21 ] キミの実力を見せてみろ
270 名前:デフォルトの名無しさん mailto:sage [2010/01/26(火) 16:28:23 ] マルチスレッドと何の関係が
271 名前:デフォルトの名無しさん [2010/01/26(火) 16:32:31 ] スレ違いでした。 すいません・・
272 名前:デフォルトの名無しさん mailto:sage [2010/01/26(火) 17:10:35 ] VCでマルチスレッドアプリをトレース実行してるとかなりの頻度でOSごと固まるんですが、 マルチスレッドの場合のデバッグはデバッガ使わないのが普通なんですか?
273 名前:デフォルトの名無しさん mailto:sage [2010/01/26(火) 17:48:30 ] PCが貧弱
274 名前:デフォルトの名無しさん mailto:sage [2010/01/26(火) 18:05:06 ] 嫁が貧乳
275 名前:デフォルトの名無しさん mailto:sage [2010/01/26(火) 18:13:39 ] ユーザが頻尿
276 名前:デフォルトの名無しさん mailto:sage [2010/01/26(火) 18:19:25 ] >>272 詳細なテキストサービスをオフにすると少し幸せになれるかも。 ATOK使いの俺には無縁な話。
277 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 23:21:31 ] 最近スレッド使い始めました。 クリティカルセクションとかインターロックで変数を共有するのは なんとなく分かりました。 例えばCRITICAL_SECTIONを使う場合、アプリケーションで一つ用意すれば よいのでしょうか? 極端に言えばCRITICAL_SECTIONをグローバル変数として定義して、 EnterCriticalSection等を使えばよろしいのでしょうか?
278 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 23:33:23 ] トイレに例えるなら何個個室があっても鍵がすべて連動してトイレにはひとりしか入れないってことだぞ それでいいのか?
279 名前:デフォルトの名無しさん mailto:sage [2010/02/02(火) 23:44:28 ] それでも良いが性能は良くない 性能向上のためにスレッドを使っているわけではないのなら、別に構わない 無理にシングルスレッドで処理するよりマルチスレッドの方が可読性が高くなることもあるからな 性能を上げたいのなら一人がどこかでロックを握ってる間全員が待たされるような構造は良くない
280 名前:277 mailto:sage [2010/02/03(水) 00:18:41 ] なるほど。問題点の指摘ありがとうございます。 では、3つスレッドがあるとして、1つは無関係で2つのスレッドで 変数を共有する場合は、クリティカルセクションをどう使えば よろしいのでしょうか? 各スレッドループ中にCRITICAL_SECTIONを定義してりようすればよろしいのでしょうか? 何か根本的に勘違いしている気がしている気がします。
281 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 00:32:42 ] 共有する変数がグローバルで1個しかないのならクリティカルセクションもグローバルで1個でいいよ
282 名前:277 mailto:sage [2010/02/03(水) 00:50:34 ] 現在は全体からアクセスできる変数が一つです。 一気にやろうとはしないで少しずつ複雑なパターンを試してみます。 あと環境はWindowsです。失礼しました。
283 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 01:35:14 ] まあロックが1つで済むならデッドロックとか考えなくて済むし 可能ならその方が悩まない。 パフォーマンスの問題は、占有期間次第とも言えるから。
284 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 02:19:04 ] クリティカルな部分一個をトイレの個室一つと考える
285 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 04:12:03 ] たまに鍵かけないやつがいてトラブるんだ
286 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 07:23:37 ] そうするとトイレの中に トイレがあって、その中にまたトイレがないと 説明不可能だろ。 トイレはネストできねーだろ
287 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 09:11:21 ] そうかクリティカルセクションはネスト出来たか
288 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 11:33:20 ] じゃあトイレがバスルームにあるということで
289 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 11:42:57 ] 階層数に制限があるからダメ。
290 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 11:52:56 ] トイレ中に地震がくるのと 小便中に大便を催すのと どっちが我慢できる?
291 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 13:45:14 ] メモリバリアとmutexの関係が解りません。 メモリバリアとmutexがどういうものか。とかじゃなくて、 関係性とか、必要とされる場面について解説してあるサイトないですか?
292 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 13:59:08 ] メモリバリア 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 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 16:33:38 ] メモリバリアかアトミック命令が無いとMutexは実装出来ない
294 名前:デフォルトの名無しさん mailto:sage [2010/02/03(水) 20:55:32 ] >>291 は同期処理のバリアのことじゃないの? 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 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 17:45:59 ] >>286 クリティカルセクションのネストって必要かな?
296 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 17:49:29 ] クラスのスレッドセーフなメソッドから同クラスのスレッドセーフなメソッドを呼び出す場合とかにあると便利かも そういう動作を意図しなかった場合にバグらないっていう利点もあるね
297 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 17:55:39 ] 同クラスなら同期処理しないプライベートメソッドを呼び出すのではないか
298 名前:デフォルトの名無しさん mailto:sage [2010/02/04(木) 19:04:48 ] たとえば口座aから口座bに振替をおこなうには、 口座aと口座b両方のロックを取る必要がある、 という典型的な例は?
299 名前:デフォルトの名無しさん mailto:sage [2010/02/05(金) 08:24:35 ] それは二つのCSをロックするだけでネストじゃないんでね?
300 名前:デフォルトの名無しさん mailto:sage [2010/02/05(金) 09:08:04 ] こんな話題とメモリバリアの話題が同時進行するってかなりカオスな気がする
301 名前:デフォルトの名無しさん mailto:sage [2010/02/05(金) 13:10:17 ] >>298 同時に入ってる必要は無くね?
302 名前:デフォルトの名無しさん mailto:sage [2010/02/05(金) 21:40:05 ] 両方とも、a→bの流れならトランザクションだけでよくないか?
303 名前:デフォルトの名無しさん mailto:sage [2010/02/06(土) 00:40:47 ] スレッドがA、B、C、Dの4つあって かならずA、B、C、Dの順番で仕事が 終わるようにするには どんなアルゴリズム使えばいいのですか?
304 名前:デフォルトの名無しさん mailto:sage [2010/02/06(土) 00:46:46 ] スレッド化する意味あるのか? B,C,Dは寝かせておいて、Aが自分の仕事を終えたときにBを起こせばいいんじゃないか
305 名前:デフォルトの名無しさん mailto:sage [2010/02/06(土) 13:44:25 ] スレッドの終了処理を順番にやる必要があるってことかな。 終わるタイミングを調整したいだけなら、 BがAの終了を待つ CがBの終了を待つ DがCの終了を待つ って感じにやれば順番に終われるんじゃね?
306 名前:デフォルトの名無しさん mailto:sage [2010/02/06(土) 18:28:33 ] そしてAがDの終了を待てば完璧
307 名前:デフォルトの名無しさん mailto:sage [2010/02/06(土) 19:34:45 ] >>306 どうやって全部待てばいいの?
308 名前:デフォルトの名無しさん mailto:sage [2010/02/06(土) 20:36:58 ] Eに管理してもらう
309 名前:デフォルトの名無しさん mailto:sage [2010/02/06(土) 20:51:33 ] どうやるのか全然わからない たすけて
310 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2010/02/06(土) 22:16:11 ] >>310 >スレッドで破れるBarrier こんなことすると破綻すると思うのですが それは何か新しい概念なのでしょうか?
312 名前:デフォルトの名無しさん mailto:sage [2010/02/06(土) 22:46:53 ] >>311 >>294 のバリアのことだよ。 2個のスレッドがバリアに到達した瞬間にバリアが破れて同時に進行を再開する。 Wikipediaより… 並列コンピューティングにおけるバリア(英: Barrier)とは、同期方法の一つであり、 ソースコード中でスレッドやプロセスがある箇所で停止し、 他の全てのスレッドプロセスがバリアに到達するまで進行しないようなものを示す。
313 名前:デフォルトの名無しさん mailto:sage [2010/02/07(日) 00:29:35 ] >>310 わかりにくい表現だな。
314 名前:デフォルトの名無しさん mailto:sage [2010/02/07(日) 21:28:39 ] 同期なり待機って言った方がわかりやすいな
315 名前:デフォルトの名無しさん mailto:sage [2010/02/11(木) 00:13:07 ] 追加削除順序を保持しつつ 効率的にアクセス可能なデータ構造って何があるの?
316 名前:デフォルトの名無しさん mailto:sage [2010/02/11(木) 00:25:04 ] 二分木
317 名前:デフォルトの名無しさん mailto:sage [2010/02/11(木) 00:32:33 ] >>316 マルチスレッドの2分木のサンプル 教えて
318 名前:デフォルトの名無しさん mailto:sage [2010/02/11(木) 00:50:06 ] >>315 Skip list. 実装例は java.util.concurrent.ConcurrentSkipListSet とかかな。
319 名前:デフォルトの名無しさん mailto:sage [2010/02/20(土) 11:14:34 ] C++のマルチスレッドの本って どんなのがありますか? Intelの本は使い方しか書いてないで 困ってる
320 名前:デフォルトの名無しさん mailto:sage [2010/02/20(土) 12:39:32 ] 正直、使い方だけしか提示しようがない気がする どこもかしこも開拓中で、定番というものが無い
321 名前:デフォルトの名無しさん mailto:sage [2010/02/21(日) 18:06:11 ] >>319 Java並行処理プログラミングマジオススメ。 直接同じことは出来なくても、考え方は大いに参考になる。 volatileだけはC++と全くの別物なので注意だけど。 boost.threadのfutureでJavaのExecutorフレームワークに近いことが出来そうだなぁ。
322 名前:デフォルトの名無しさん mailto:sage [2010/02/21(日) 18:16:04 ] >>321 その程度の書籍薦められても困るんだよ もっとまともな本持って来い
323 名前:デフォルトの名無しさん mailto:sage [2010/02/21(日) 18:29:39 ] >>322 Java並行処理プログラミングでも満足できない貴方には ↓がお勧め。 scholar.google.com/ 最先端の研究成果が大量に手に入るぞ。
324 名前:デフォルトの名無しさん mailto:sage [2010/02/21(日) 19:01:28 ] >>322 もっとまともな本があるなら俺も知りたいけどね。
325 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2010/02/22(月) 16:42:48 ] beginthreadexが返したハンドルを渡すのかと聞いているのならYES
328 名前:デフォルトの名無しさん mailto:sage [2010/02/22(月) 17:44:29 ] _beginthreadexはなんで整数型で返すんだろう
329 名前:デフォルトの名無しさん mailto:sage [2010/02/22(月) 22:11:07 ] Win32の型を持ち込みたくなかったからじゃないの。
330 名前:デフォルトの名無しさん mailto:sage [2010/02/23(火) 00:27:00 ] 意味も無く汚くはしないしな、いくらMSでも
331 名前:デフォルトの名無しさん mailto:sage [2010/02/23(火) 00:29:08 ] void *じゃだめなのか
332 名前:デフォルトの名無しさん mailto:sage [2010/02/23(火) 08:52:12 ] それだと32bitであることを強調できないからやめたんじゃないかな
333 名前:デフォルトの名無しさん mailto:sage [2010/02/23(火) 14:32:40 ] 一応今はuintptr_tだしな まぁ毎度のレガシーの枷なんだろうし、仕方ないっつーか正直どうでもいい
334 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 16:24:51 ] A1: Windows 98, 2000以降はyes A4: yes
336 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 16:51:28 ] A2 コア別でしょう。たぶん。コア間共有なんて設計のほうが難しいと思うよ。 A3 コア別でしょう。たぶん。コア間共有なんて設計のほうが難しいと思うよ。
337 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 18:07:36 ] 何のために_beginthread()〜_endthread()や_beginthreadex()〜_endthreadex()があるかというと strtol()みたいに、機能的にはマルチスレッド環境下でも動いて欲しいのだが関数仕様的にマルチスレッドと相容れないような 標準関数をマルチスレッド環境でもきちんと動くようにする目的なので(おそらくそのために内部的にスレッド局所記憶を確保している) そういう類の関数を明示的にも暗黙的にも呼び出さないと誓うならCreateThread()〜CloseHandle()で無問題
339 名前:308 mailto:sage [2010/03/07(日) 18:19:56 ] スマソstortol()じゃなくて問題なのはstrtok()とかlocaltime()とかだった、
340 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 18:53:55 ] >>337 _beginthread は起動されたスレッドが終了時にハンドルのクローズを行う。 _beginthreadex は別途CloseHandleする必要がある。その代わり、 スレッドが終了していてもハンドルは有効であり、スレッドの状態を調べることができる。 ここでのリークというのはCRTの作業域のことではなくて あくまでもスレッドを追跡するためのハンドルのこと。
341 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 22:27:39 ] >335, >336 レスdクス A1は実験的にも確認できた(イントリンシック関数が排他を含まないこと、およびxmm0とxmm1を使う関数を64スレッドで呼び出して無問題) A2はまあそう思う(ダイ写真でSIMDとコアの区別を確認できない&SIMDの数<コアの数ではマルチメディア目的に合致しない) A4についても使用予定関数について実験的に確認できた A3はちょっち謎 同一コードで記述され、同一コアで走る別スレッド(含HT)の場合どうなるのか? 同一コード条件とそうでない条件(コードをスレッド別コピーとする)とで速度比較すればいいんだろうけども コードをコピーすると分岐予測以前にトレースキャッシュ容量他の要因で速度低下するかもしれないから実験では精度良くは判断できない鴨
342 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2010/03/08(月) 00:39:08 ] どうやって確認したの?
344 名前:デフォルトの名無しさん mailto:sage [2010/03/08(月) 00:45:01 ] 何がしたいのかよくわからんが、 とりあえずmutex取得する前にシグナル発行してたらいかんだろう。
345 名前:デフォルトの名無しさん mailto:sage [2010/03/08(月) 00:54:13 ] thread1がlockするまえにmainがlock->signalしちゃってるとかありそう
346 名前:デフォルトの名無しさん mailto:sage [2010/03/09(火) 07:06:51 ] >>337-338 つーか比較するものが間違ってる _endthread()/_endthreadex()は作られた側が(必要なら)呼び出すもので CloseHandleは_beginthread()/_beginthreadex()呼んだ側が呼び出すもの
347 名前:341 mailto:sage [2010/03/13(土) 23:42:54 ] 自己解決しますた!(いや、多分、だけど Windowsのスレッドコンテキスト切替は、スレッドが走り続けている場合、どうがんばっても msオーダー周期(おそらく10 msとか20 msに1回)なので、分岐予測統計の結果がその間に十分安定する(と思われ だから分岐予測精度を上げるためにコードのコピーをスレッド別に用意しておく、みたいな神経質なことはしなくて宜しい かと、
348 名前:342 mailto:sage [2010/03/14(日) 01:04:34 ] 訂正 誤:分岐予測統計の結果がその間に十分安定する(と思われ 正:分岐予測統計の結果が現実的に安定している期間よりも桁違いに長い(と思われ ニホンゴ、ムズカシイデス、、
349 名前:デフォルトの名無しさん mailto:sage [2010/03/14(日) 02:03:43 ] いやいやいやいや いまはコア間での話ではなかったのか?
350 名前:デフォルトの名無しさん mailto:sage [2010/03/14(日) 08:00:00 ] またえらい細かいオーダーで削ってるんだなぁ。 PCのWindowsでそこまでカツカツ削っても、すぐに時代変わっちゃうと思うけどなぁ。 他のとこに力入れた方が良くね? まぁ、トレースキャッシュとか気にしてるから、何か特殊な固定環境向けのガリガリな チューニングなのかもしれないけど。 俺も低レベルは好きだから、とりあえず触ることで知識と感覚を深めたい、ってんなら 止めないけど。単にバランス感覚の欠けてるケースに見えてしまうが。違ったらすまん。
351 名前:デフォルトの名無しさん mailto:sage [2010/03/14(日) 08:19:21 ] >>349 分岐予測メモリはCore i7の場合物理コアごとに持ってるからスレッドごとに物理コアを違える場合は何も悩む必要はない 問題なのはスレッドの数が物理コア数より多いとか、同一物理コア内でのHTの場合(→341の下から3行目参照)
352 名前:デフォルトの名無しさん mailto:sage [2010/03/14(日) 08:30:59 ] ハッよく考えたら>348-349のロジックじゃあHTの場合が解決してねーじゃんorz 同一コア内で走るHT0とHT1は、ハードウェアレベルで演算ユニット、L1, L2キャッシュ、トレースメモリを奪い合うので もし仮に分岐予測メモリのタグがアドレスのみから生成され、HT番号では区別されない作の場合問題になりえる ただしまあ現実的には同じアドレスに配置された同じ条件分岐命令が 1. HT0とHT1でほぼ同時に(=分岐予測結果の平均寿命(おそらく数μsec)オーダーの時間差内に)実行されるという状況が 2. 片方は分岐、片方は非分岐で 3. 無視し得ない頻度で反復される というケースでのみ問題だが >>350 というわけでWindows非依存な話
353 名前:デフォルトの名無しさん mailto:sage [2010/03/14(日) 08:32:37 ] >>352 いや本人がWindows7を対象にしてるって最初に言ってるから
354 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [2010/03/27(土) 15:08:07 ] ここのコメント欄みづらいんだよね 最初の「必要以上に複雑になってる」という指摘は同意。 この記事って、バグのあるコードをだんだん直していくっていう 流れだけど、そもそもタイトルの条件変数関係ないバグだし、 修正内容も、なんか泥沼に入っていくような感じ その後のやりとは、この二人にしか分からないどうでもいいことについて、 どうでもいいやりとりしてるように見えた。
357 名前:デフォルトの名無しさん [2010/03/27(土) 15:20:18 ] >>338 これはわかりやすい!
358 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 23:05:41 ] 「Java並行処理プログラミング」が増刷してる
359 名前:デフォルトの名無しさん mailto:sage [2010/04/18(日) 10:57:03 ] va_argsってスレッドセーフですか?
360 名前:デフォルトの名無しさん mailto:sage [2010/04/18(日) 21:21:11 ] va_list を自動変数やTLBに置いていれば、va_listをスレッド間で共有しない限りは、スレッドセーフだと思うぞ。
361 名前:デフォルトの名無しさん mailto:sage [2010/04/18(日) 22:11:15 ] >>360 嘘ついちゃだめ va_listはプロセスで1つだけしか持てないから スレッドセーフじゃないよ
362 名前:デフォルトの名無しさん [2010/04/19(月) 00:34:37 ] ボナンザ8コア対応を16コア対応にする方法を教えて下さい。
363 名前:デフォルトの名無しさん mailto:sage [2010/04/19(月) 06:51:44 ] スレッドセーフかどうかってのはcrtのソース見ないと判断付かないって認識でおkっすか?
364 名前:デフォルトの名無しさん mailto:sage [2010/04/19(月) 07:04:05 ] >>361 適当ぶっこくなカス
365 名前:デフォルトの名無しさん mailto:sage [2010/04/19(月) 07:18:38 ] >>364 じゃあ証明してくれよ できないだろw?
366 名前:デフォルトの名無しさん mailto:sage [2010/04/19(月) 07:28:20 ] >va_listはプロセスで1つだけしか持てない
367 名前:デフォルトの名無しさん mailto:sage [2010/04/19(月) 07:59:36 ] それとスレッドセーフの話にどんな関係が?
368 名前:デフォルトの名無しさん mailto:sage [2010/04/19(月) 08:31:37 ] >>365 簡単。 va_listはプロセスで複数もてるから スレッドセーフ
369 名前:デフォルトの名無しさん mailto:sage [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 mailto:sage [2010/04/21(水) 15:37:33 ] >>369 方法はあるけど、物凄くマヌケで無意味だから誰もやらない。
371 名前:デフォルトの名無しさん mailto:sage [2010/04/21(水) 19:01:35 ] スレッドとかの切り替えを自前で用意するとか
372 名前:369 mailto:sage [2010/04/22(木) 09:40:25 ] いろいろと試してみたのですが、マヌケな方法しか思いつきませんでした。 (スピンを何回かしたら、nanosleepを使うとか) pthreadのライブラリのソースを見てみると、futexのシステムコールが呼ばれているようですね。 OpenMPで生成したスレッドの中で実行される関数間でスレッドの同期をとりたかったのと、 せっかくOpenMPを使っているから、 pthreadとか使いたくなかったので自前のspin_lockを作ってみました。 マヌケな質問をしてすみませんでした。
373 名前:デフォルトの名無しさん mailto:sage [2010/05/08(土) 03:22:14 ] ヒント:スピンロックを使わない
374 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 22:01:03 ] Win32でスレッド間のイベント通知をやりたいんですが 2つのスレッドが同時にそれぞれSetEvent(), ResetEvent()を呼び出した場合の動作って定義されてるんでしょうか? やっぱりクリティカルセクションで囲ってやらないとまずいですか?
375 名前:デフォルトの名無しさん mailto:sage [2010/05/09(日) 22:39:08 ] >>374 囲む必要は無い。
376 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 08:17:54 ] >>375 ありがとうございます。
377 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 20:41:23 ] イベントオブジェクト自体の動作には問題ないけど、 使い方ミスりやすいから十分気を付けた方がいいよ。
378 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 23:08:00 ] プロのコードではイベントオブジェクトは使われない
379 名前:デフォルトの名無しさん mailto:sage [2010/05/10(月) 23:37:24 ] 配布したときに問題が出るからな
380 名前:デフォルトの名無しさん mailto:sage [2010/05/11(火) 03:50:40 ] どんな?
381 名前:デフォルトの名無しさん mailto:sage [2010/05/12(水) 22:45:33 ] 無名にすれば他のプロセスと衝突することも無いし、kernel32.dllだから別にDLLも不要だし問題が思いつかないな
382 名前:デフォルトの名無しさん mailto:sage [2010/05/13(木) 07:37:01 ] なんか勘違いしてんだろ
383 名前:デフォルトの名無しさん [2010/05/16(日) 21:15:32 ] wait-freeなキューの実装を可能にするのに必要な不可分操作ってどんなんですか?
384 名前:デフォルトの名無しさん mailto:sage [2010/05/16(日) 23:08:56 ] 候補となる不可分操作には何があるの?
385 名前:383 [2010/05/16(日) 23:57:41 ] >384 JAVAのConcurrentLinkedQueueだとCASをつかってるってことしか知りませんが..
386 名前:デフォルトの名無しさん mailto:sage [2010/05/18(火) 00:45:56 ] wikiによるとcasみたいだね ja.wikipedia.org/wiki/Lock-free%E3%81%A8Wait-free%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0
387 名前:デフォルトの名無しさん mailto:sage [2010/05/20(木) 23:12:58 ] スレッド間のヘルスチェックに定番な方法ってあるのでしょうか? ・マスターなスレッドAが外部変数にスレッド数分bit1を立てる ・B以降のスレッドは、自分に対応するbitを落とす ・一定時間、0じゃなかったら誰かが止まってるのでNG とかすると、sem_wait()で普段寝ている人(これはその時だけ起こせばいい?)や、 recvやselectで待ってる人の確認はできない。。
388 名前:デフォルトの名無しさん mailto:sage [2010/05/21(金) 00:00:00 ] スレッドのヘルスチェックって要るのかな?プロセス間だったら必要かも知れなけど。
389 名前:デフォルトの名無しさん mailto:sage [2010/05/21(金) 00:05:09 ] 大事な役割を持ったスレッドが刺さってないか確認したいんじゃないの
390 名前:デフォルトの名無しさん mailto:sage [2010/05/21(金) 01:47:25 ] タイムアウト指定して待ちっぱなしにならないようにするのが基本
391 名前:デフォルトの名無しさん mailto:sage [2010/05/21(金) 18:56:29 ] ワーカースレッドとUIスレッド分けたとき、時間のかかる作業を ワーカースレッドがしているとき、UIスレッドはどうしているべきでしょうか 今は終わるのを待たずに終わるまでデータ変更の起こる操作を禁止しています でもそれだとウィンドウ動かせるくらいしかメリットがないので考え中です
392 名前:デフォルトの名無しさん mailto:sage [2010/05/21(金) 19:03:15 ] >>391 俺は[中止]ボタンが押されるのを待つか、タイマーで定期的に終了したかどうか チェックしてる。あとプログレスバー表示。
393 名前:デフォルトの名無しさん mailto:sage [2010/05/21(金) 19:49:50 ] ボタンを禁止にしたりキャンセルを受け付けたり面倒だよな それとプログレって、量的な変化ならいいが、 手続き的な進行表示には不向きだよな
394 名前:デフォルトの名無しさん mailto:sage [2010/05/21(金) 20:05:26 ] 全体量がわからないやつはつらいよね \-/-\-...ってやつが好きw
395 名前:デフォルトの名無しさん mailto:sage [2010/05/21(金) 21:03:40 ] 経過表示なら1/n「(説明)」〜n/n「完了」でいいと思うんだ
396 名前:デフォルトの名無しさん mailto:sage [2010/05/24(月) 23:34:30 ] progress_display「呼んだ?」
397 名前:デフォルトの名無しさん mailto:sage [2010/05/25(火) 09:11:50 ] いや、全然呼んでないよ
398 名前:デフォルトの名無しさん mailto:sage [2010/06/26(土) 14:48:12 ] マルチスレッド・アプリケーション開発のためのインテル・ガイド 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 名前:デフォルトの名無しさん mailto:sage [2010/07/02(金) 23:09:47 ] ttp://blogs.wankuma.com/jitta/archive/2010/02/05/185818.aspx なんかえらい絡まれてるくらい突っ込まれてるみたいなんだけど やっぱりこの記事おかしいの? それともコメントの方がおかしい?
402 名前:デフォルトの名無しさん mailto:sage [2010/07/02(金) 23:28:25 ] >>401 バブルソートを題材にするとか並列化のサンプルとして適切じゃないというかフェアじゃないというか、あえてそれを選ぶのはなぜ?って話でしょう。
403 名前:デフォルトの名無しさん mailto:sage [2010/07/02(金) 23:40:12 ] >何でもかんでも並列化すれば、等しく速くなるわけではない 記事の結論には同意だけど記事書いてるひとはアホ
404 名前:デフォルトの名無しさん mailto:sage [2010/07/03(土) 02:56:46 ] >>403 同意だな。 並列化に向いたアルゴリズムをつかわにゃ早くならんしな。 ていうか変数shareしすぎ。
405 名前:デフォルトの名無しさん mailto:sage [2010/07/03(土) 08:13:40 ] だらだらと下手糞なコードを書いて速くならねえよと喚かれてもな そんな記事にはほとんど価値がない
406 名前:デフォルトの名無しさん mailto:sage [2010/07/03(土) 09:47:23 ] 結局バグってたっぽいw コメントが間違ってなければだが。
407 名前:デフォルトの名無しさん mailto:sage [2010/07/03(土) 10:07:39 ] 記事自体は、アルゴリズムによって効率的に並列化できるとは限らないから云々んという内容なので、 記事自体が(素人にとっては)無意味だとまでは言わんが、 この人偉そうな言い方したり他人の記事に対しては重箱レベルで突っ込んだりもしてるくせに 自分の記事は内容が結構いい加減なんだよな。
408 名前:デフォルトの名無しさん mailto:sage [2010/07/03(土) 11:48:12 ] そんな人は世間にはいっぱいいる