マルチスレッドプログラミング相談室 その7at TECH
マルチスレッドプログラミング相談室 その7 - 暇つぶし2ch440:デフォルトの名無しさん
09/02/26 23:51:02
>>435
実質、4coreXeonのシステムだとOpenMPで4スレッドにして3.9倍速くなるけどね。
逆に、>435のCPUはOSをアイドル状態で動かすだけでどんだけ負荷喰ってるんだって話だな。

441:426
09/02/27 10:22:04
>>440
スレッドでどんなコードを走らせているか知らないけど、スレッド内で
アクセスするデータもコードも、CPU内のキャッシュに収まるくらい
小さなプログラムでもない限り、そういう結果はまずありえないと思うな。

それとも脳内キャッシュ?

442:426
09/02/27 10:43:15
非同期I/Oを使わずスレッド内でファイルI/O待ちしているとか、ネット
ワーク物理層の帯域幅に比べて通信速度が遅く、スレッド化でマルチ
セッション化できるといった、ある意味冗長な造りのプログラムなら
ありえるね。

OSのアイドル状態を持ち出すあたり、他に何個のプロセスがいつ走って
いるか考えていないのかな?(w

443:デフォルトの名無しさん
09/02/27 10:43:58
>>441
OpenMP知らないなら黙っていた方がいいと思うよ。

444:デフォルトの名無しさん
09/02/27 10:45:51
>>443
3.9倍早くなるって
作ったプログラム全体?それとも特定の処理に
限定された内容?どっちなの?

445:443
09/02/27 11:04:31
>>444
私に聞くなw
恐らく演算に集中している部分じゃないの?
MKLなんかは大き目のデータのFFTでそれくらいのリニアリティを叩き出すから。

446:デフォルトの名無しさん
09/02/27 13:15:48
embarrassingly parallel なワークロードならそれくらい行ってもおかしくない

でも大抵の処理は並列化不可能な部分が無視できない量存在してて、
アムダールの法則でもって高速化の限界が簡単に見えてしまうと思うよ

447:デフォルトの名無しさん
09/02/27 13:58:29
>>436
コンシューマー相手のソフトウェアのパッケージ販売の観点からは
明らかに優れている。全然スレ違いだが。

448:デフォルトの名無しさん
09/02/27 19:47:19
>>443
OpenMP に期待しすぎ。

何でもかんでも 3.9倍になる魔法なら俺も欲しいが。(w

449:デフォルトの名無しさん
09/02/28 02:39:25
>デュアルコアやクァッドコアのCPUだと、マルチスレッド化すると理論上
>2倍や4倍で動くと勘違いしているヤツもたまにいるよね。おまえのOSは
>いったいいくつプロセスが動いていると思っているんだと、小一時間。(略

略とか言われても。誰か解読してあげてよ。
少なくとも実測で3.9倍でてるわけだから、理論上は4倍出ると言っても問題ないよな。
たくさんのプロセスが動いてるとき、マルチコアだとちゃんと速くなるよな。
意味不明。

450:デフォルトの名無しさん
09/02/28 03:13:14
どういう問題を解いて3.9倍なのか書かないと意味がないかと。

知人の計算屋さんがAMDの8CPU機にメモリしこたま積んで
巨大グラフを相手にした問題を解いていたことがありましたが、
問題の構造上メモリアクセスに局所性が全くないのでCPUの
速度や数以前にメモリ帯域が飽和して速度が頭打ちになると
ぼやいていた事が。

451:デフォルトの名無しさん
09/02/28 14:17:04
>>450
まあその辺に桁違いのコストを掛けてクリアしてることが
スパコンの存在意義だしね


452:443
09/02/28 16:53:30
>>448
期待するも何も、実験した結果だし。

>>450
>445に書いた通り、只管FFTを計算するようなプログラムと言うくらい。

その結果では、4core2cpuのシステムで、4並列まではびっくりするほどリニアリティがあるけど、
その先は一つ増やしても0.7個分くらいしかパフォーマンスが上がらなかった記憶が。
# 8並列で7倍くらいかな? 必要なら記録を探してくるけど。

尤も、自作のプログラムだと4並列でも8並列でも殆ど変わらなくて泣けた罠。
インテル某氏の話だと、MKLはOpenMPで並列化してもリニアリティを確保できるように
作られているそうで、折角FFTを使わない版を作ったのにお蔵入りになりそうだったり。

453:デフォルトの名無しさん
09/02/28 16:55:08
スパコンと言えばTOP500で10位にWin鯖クラスタが付けてたけど
(CPUとメモリだけ)似たような構成の他のと比べて特に劣ってるようでも秀でてるようでもなかった

454:デフォルトの名無しさん
09/02/28 18:46:09
>>452
OpenMP に頼って満足してる人はこのスレに用はないでしょ。
どうぞお引取りください。

455:デフォルトの名無しさん
09/02/28 19:01:43
>>454
>452じゃないけどここはマルチスレッド全般でしょ?
>1にも「OS・言語・環境は問わない」って書いてるんだからいいと思うけど
ただし>452=443=440はおバカさんだと思うけどねw

456:デフォルトの名無しさん
09/02/28 21:22:08
OpenMP の話題がまずいと言ってるわけじゃなくて、「OpenMP
に頼って満足してる人」って書いてあるんだが...。

スレタイに「相談室」って書いてあるのが見えませんか?

457:デフォルトの名無しさん
09/02/28 21:41:20
>>456
相談した人にOpenMPに頼って満足してるってレスするのは問題ないだろ

458:デフォルトの名無しさん
09/02/28 22:04:33
で、どこに相談した人がいるんだ? (w

459:デフォルトの名無しさん
09/02/28 22:09:48
俺は>452個人の話はしてないんだが。お前誰と闘ってるんだ?

460:452
09/02/28 22:13:07
まぁ、私は「OpenMPに頼って満足してる」のではなく、「OpenMPを巧く使うMKLに勝てなくて泣いてる」のだけれどねw

461:デフォルトの名無しさん
09/02/28 22:13:48
よくわからないけど、置いときますね。
#light
open System.Threading
let tid = fun () -> Thread.CurrentThread.ManagedThreadId
let sleep = fun (t:int) -> System.Threading.Thread.Sleep t
let x1() = [|1..100|] |> Array.map(fun x -> sleep(100); [|x ; tid()|])
let x2 = [|1..100|] |> Array.map(fun x -> async { sleep(100); return [|x ; tid()|] } ) |> Async.Parallel
let _ = printfn "%A" (x1()); printfn "%A" (Async.Run x2)


462:デフォルトの名無しさん
09/02/28 22:35:01
>>450
おれは、>>452 個人の話をしてるんですけど。

まさか、>>454 に書いてあるアンカーすら見えなくなるほど
頭に血が上ってるとか? (w

463:デフォルトの名無しさん
09/02/28 22:48:56
>>462
俺は「OpenMPに頼って満足してる」のを理由に追い出そうとしたことに
ついて話をしている。>>452個人のことはどうでもいい。
どうやらただの煽りあいになりそうだからこの話題は終了する。

464:デフォルトの名無しさん
09/03/01 02:32:16
>>460
何故勝てなくて泣く必要があるのか少し気になる。

465:デフォルトの名無しさん
09/03/01 16:47:46
>>463
「相談した人もいないのに勝手に OpenMP に頼って満足してる人」は
このスレに用はないでしょ。

これでいいか?

> >>452個人のことはどうでもいい。

# >>452 にレスしてるのに、勝手に割り込んできて逆切れかよ...

466:デフォルトの名無しさん
09/03/01 18:49:02
OpenMPってどんなの?たとえば、Videoのエンコード・デコード
処理が書いてある逐次処理のCなりC++のソースコードが
あったら、ほとんど変更なしに並列化できるん?

それとも、既存のソースは一から書き直しくらいしないと
パフォーマンスは出ない?

467:デフォルトの名無しさん
09/03/01 18:53:11
相談者が現れたので>>452の出番ですwww

468:デフォルトの名無しさん
09/03/01 18:55:20
それ以前に446にふさわしい言葉は「ググれカス」だろう。

469:デフォルトの名無しさん
09/03/01 19:14:45
>>466
OpenMPスレという物もあってだな(ry

470:デフォルトの名無しさん
09/03/02 02:02:51
OpenMP詳細しらんが、既存のソースは1から書き直しまで
いかなくても、大幅に書き直さないとパフォーマンスは
でないのだろうな。常識的に考えて。

コア数に応じてリニアにパフォーマンスがあがって、既存
のソースから簡単に移行できますよ、っつーなら神なのだが。

471:デフォルトの名無しさん
09/03/02 02:35:03
それを可能にするには関数型など副作用のない言語が有利
今更言うことでもないが

472:デフォルトの名無しさん
09/03/02 02:38:08
>>471
んなこたーわかってんだよ。新規にはじめる分野はそれでもえーよ。
資産の移行も重要なんだよ。

473:デフォルトの名無しさん
09/03/02 02:42:00
おまえの書いたコードなんぞ資産と呼ぶ価値も移行する価値も無いから気にすんな

474:デフォルトの名無しさん
09/03/02 02:46:42
>>473
俺の書いたコードが資産だなんて、いついったんだよ?
煽るにしろ、頭の悪さが透けてるんだよ。

475:デフォルトの名無しさん
09/03/02 03:08:36
>>472の「おまえ」が>>474だなんて、いついったんだよ?
煽るにしろ、頭の悪さが透けてるんだよ。

476:デフォルトの名無しさん
09/03/02 11:59:03
これは惨めなミス。

477:デフォルトの名無しさん
09/03/02 13:39:15
>デュアルコアやクァッドコアのCPUだと、マルチスレッド化すると理論上
>2倍や4倍で動くと勘違いしているヤツもたまにいるよね。おまえのOSは
>いったいいくつプロセスが動いていると思っているんだと、小一時間。(略

478:デフォルトの名無しさん
09/03/02 23:44:21
>>477
こいつの言ってることまじでわからんのだが・・・。
こいつがアフォなのか、俺がアフォなのか誰か解説よろしく!

479:デフォルトの名無しさん
09/03/03 00:03:02
コア1 ●◎◎◎◎◎◎◎◎◎
コア2 ●○○○○○○○○○
コア3 ●○○○○○○○○○
コア4 ●○○○○○○○○○

         ↓

コア1 ●◎◎◎◎◎◎◎◎◎
コア2 ●◎◎◎◎◎◎◎◎◎
コア3 ●◎◎◎◎◎◎◎◎◎
コア4 ●◎◎◎◎◎◎◎◎◎

○ 空き
● 別プロセス
◎ 自プロセス

4倍になる

480:デフォルトの名無しさん
09/03/03 00:28:55
>>477
基本的には>>477がちょっとずれていると思う。
コア数に比例してリニアに2倍4倍にならないのは事実。
でもハウスキーピングなプロセスの数云々は性能を押し下げる
理由としてはどちらかというとマイナーな部類だと思う。

481:デフォルトの名無しさん
09/03/03 00:29:19
ちょっとゲロでちゃった

482:デフォルトの名無しさん
09/03/03 00:35:18
並列化効率の話がまず最初だよね。
アムダールの法則。

483:デフォルトの名無しさん
09/03/03 00:38:03
>>480
いや、こうまで単純化していいかどうかわからんが、
ハウスキーピングのプロセスがほぼsleep状態と
仮定したら無視できるわけで。

というより、4コア100%使用する処理走らせるんだったら、
無視できるほどなわけで(スワップデーモンとか
ハードアクセスの重いスレッドが走らない前提なら)。

バスネックでリニアに伸びないとか、キャッシュの競合
だとかいうならまだしも。やっぱり俺には>>477はさっぱ
りわからん。

484:デフォルトの名無しさん
09/03/03 01:50:33
アイドル状態のプロセスでもビジーループでCPU消費してる
とか思ってんじゃないの

485:デフォルトの名無しさん
09/03/03 01:56:06
>>484
単に1つのプロセスが1コアを占有し続けると考えているのではあるまいか。

486:デフォルトの名無しさん
09/03/14 05:22:42
マルチスレッドについて質問です。
環境は VC++2005 SDK です。

子ウィンドウの WM_CREATE にて無限ループをさせても
親ウィンドウが操作できる
事を実現したいです。

他スレにて、
>Windowsのウィンドウはスレッドに属する。
>ウィンドウプロシージャはウィンドウの属するスレッドで実行される。
>さて、どのスレッドに属するかというと、CreateWindow(Ex)を呼んだスレッド。
というレスをいただき、新しいスレッドにてCreateWindow する手段を取りました。
子ウィンドウの WM_CREATE までは処理が進むのですが、
無限ループどころか for (i=0; i<100; i++) { i = i; } を WM_CREATE 内に
記述した途端にフリーズする様になってしまいました。
コメントアウトすれば、問題なく動作します。

ファイルをアップロードしたので、見ていただけないでしょうか?
URLリンク(www3.uploda.org)
受信パスは test です。
どのように修正すれば良いか、ご教授願います。
よろしくお願いします。

487:デフォルトの名無しさん
09/03/14 05:54:15
>>486
windowsのウィンドは、プライマリスレッドで生成しないと
いろいろいろいろいろいろいろいろトラブルが起こるので、そういう設計は見直した方がいい。
そもそも子ウィンドウは親ウィンドウと同じスレッドで生成しないとトラブルになる。

例えば親をAスレッドが、子をBスレッドが作ったりすると、
親のプロシージャはAスレッドが実行し、子のプロシージャはBスレッドが実行することになる。
子から親への通知や親から子への通知がメッセージで発生したら発生したら、
デッドロックの宝庫になることは想像に難くない。

それ以前にメッセージループって親子で共通のような気が・・・

488:デフォルトの名無しさん
09/03/14 06:05:38
>>486
アップロードしたプログラムだとそもそも子ウインドウは表示されないだろ。

動くようにするには子ウインドウと呼んでいるものを、新しいスレッドのウインドウにすること。
つまりメッセージループをそこでまわす。

MSG msg;
ShowWindow(hChild, SW_SHOWDEFAULT);
UpdateWindow(hChild);
while(GetMessage(&msg, NULL, 0, 0)) {
 TranslateMessage(&msg);
 DispatchMessage(&msg);
}
//static int k = 0;
//k = 1;
//while (1)
//  k++;


489:デフォルトの名無しさん
09/03/14 06:16:38
WM_CREATEで無限ループしたらCreateWindowから制御が戻らないわけだが

490:486
09/03/14 15:00:34
>>487
色々と問題があるという事ですか...
そこまでは考えておりませんでした。
ですが、今はこの枠組みで作ろうと思います。
アドバイスありがとうございます。

>>488
メッセージのループを回すのを忘れておりました。
ありがとうございます。
ただ、今回はメッセージのループのみが欲しいので
ウィンドウは非常時で構いません。

>>489
確かにそうでした。
あるメッセージを受けた時に
その中で Sleep(1000); を実行する事にしました。

・・・が、それでも親ウィンドウが 1000 ミリ秒 固まってしまいました。

以下の様にしておりますが、
これでは各ウィンドウは別スレッドで動かないのでしょうか?
URLリンク(www2.uploda.org)
受信パスは test です。
よろしくお願いします。

491:デフォルトの名無しさん
09/03/14 15:07:12
作ろうと思います、じゃねー
動作が未定義なんだからそんなプログラミングすんな

492:デフォルトの名無しさん
09/03/14 15:18:07
>>491
互いのウィンドウでメッセージのやり取りを頻繁にするような事は致しません。
親スレッドとは独立したウィンドウプロシージャのメッセージループ
(表現が合っているかは自信がありませんが)が欲しいのです。

以下、長文失礼します。

5 [msec] の情報が入るサイズのバッファを複数用意し
信号をバッファに入力し、あるバッファが満タンになったら
windows からメッセージが投げられ、
受け取ったメッセージ内で信号処理をする、
というものを作っています。
この時、信号処理に時間がかかるため
常にメッセージを受け取った時の処理を行ってしまい
メニュー操作が出来なくなる状態です。

アプリケーションを強制終了すると、信号処理した数値列が
ちゃんとファイル出力されているので
信号の入力及び信号処理は問題なく進んでいます。

これを解決するにはメニューを持つウィンドウと
メッセージループのあるウィンドウを別スレッドで走らせれば良い
と考えました。


493:492
09/03/14 15:53:32
連稿失礼します。
Sleep(1000); を

int i, j;
for (i=0, j=0; i<1000000000; i++)
j++;

としてみましたが、結果は同じでした。
親ウィンドウのスレッドにフォーカスが戻っていないのでしょうか?

494:デフォルトの名無しさん
09/03/14 16:43:47
子ウィンドウ作る必要なんて無いところを、
わざわざ回りくどいやり方しているようにしか思えないんだけど。
ワーカースレッドにデータ送りたいだけじゃないの?

495:デフォルトの名無しさん
09/03/14 18:10:18
>>494
ワーカースレッドについて知識が無かったのでググってみました。
MFCでのみ使用可能な関数でしか作れない事が判りました。
今はSDKで組んでおり、MFCは使った事が無いので今の私には使えそうにありません。
情報ありがとうございました。

496:デフォルトの名無しさん
09/03/14 18:28:36
>>495
ワーカースレッドは概念であって、SDKのみだから作れないということは無いよ

そもそも、貴方のやろうとしていること自体がワーカースレッドの利用だ

497:デフォルトの名無しさん
09/03/15 15:23:44
>>496
ワーカースレッドについて調べ方が間違っていたようです。
もっと調べを進めます。ありがとうございます。

498:デフォルトの名無しさん
09/03/15 20:09:14
>>492
ワーカースレッドというのは、作業を行うスレッドという程度の意味です。
信号処理中はGUIが不要のようですので、GUIは1個のスレッドにまとめて下さい。
以下、基本は次のような処理になります。Q0とQ1のアクセスを排他制御して下さい。
プライマリスレッド
  メインウィンドウの作成。
  バッファ群を作成する。例えば5ms用のバッファをN個作成して、
  2個のキューQ0(未使用バッファ用)とQ1(充填済みバッファ用)を作成する
  バッファを全てQ0に格納し、スレッドA・Bを作成・実行する。
  以降はGUIによるスレッドA・Bのコントロールを行う

スレッドA(バッファ充填処理)
  1.信号受信処理の初期化
  2.Q0からバッファを取り出す。無ければ待つ。
  3.バッファを充填する処理(この辺で外部からのスレッド終了通知チェック)
  4.バッファが一杯になったらQ1へ入れ、2へ戻る
  
スレッドB(信号処理スレッド)
  #スレッドAで、Q1の格納数が0->1になったとき起こされる。
  1.Q1からバッファを取り出す(なければ待つ)
  2.信号処理(この辺で外部からのスレッド終了通知チェック)
  3.結果の出力
  4.バッファをQ0へ入れ、1へ戻る

499:デフォルトの名無しさん
09/03/15 20:18:36
>>498
あー便所で説明してくれないと解らない

500:デフォルトの名無しさん
09/03/15 20:42:55
>>499
ウホッいい男!

501:492
09/03/15 20:45:19
>>498
詳しい構成、本当にありがとうございます。
頑張って理解してみます。

502:デフォルトの名無しさん
09/03/27 03:19:19
void A::sync_fun() {
  boost::mutex::scoped_lock lock(m_);
  // 何かの処理
}

上のlockで待機しているスレッドがあるときにAのオブジェクトをdeleteするとスレッドは待機したままですね。
下のようにするかtimed_waitにする必要があるのか、そこまで気にすることもないのか。
みなさんはどうされますか?

void A::sync_fun() {
  boost::mutex::scoped_lock lock(m_);
  cond_.wait(lock, bind(&A::pred, this));
  if (invalid_) return;
  // 何かの処理
}

bool A::pred() const { return stat_ || invalid_; }

A::~A() throw() {
  {
    boost::mutex::scoped_lock lock(m_);
    invalid_ = true;
  }

  cond_.notify_all();
}


503:デフォルトの名無しさん
09/03/28 18:55:17
>>502
どうするかは、何のクラスかによるだろう。
一般論でAが、sync_fun()実行中に破棄される可能性があって、
どうしても回避できないならAのデストラクタでunlockする。

504:デフォルトの名無しさん
09/04/04 16:12:48
ダウンローダをマルチスレッドで作成しようと思っているのですが
スレッドを10個作り
それぞれにURLを追加して、次々にダウンロードさせる仕様にしようかと思っていますが
このスレッドの終了タイミングはどういった条件で終了すればいいでしょうか?

メインスレッドが終了するとこの10個のスレッドも終了するので
どうしたものかと考えています

505:デフォルトの名無しさん
09/04/04 16:19:45
あげます
すいません

506:デフォルトの名無しさん
09/04/04 16:20:37
.

507:デフォルトの名無しさん
09/04/04 16:36:26
>>504
何を聞きたいのかよく分からんけど、
メインスレッドで10個のスレッドの
終了待ちさせれば良いんでないの。

508:デフォルトの名無しさん
09/04/04 16:45:56
>>507
なるほど
そういう手がありましたか
ありがとうございました

509:デフォルトの名無しさん
09/04/04 17:26:41
何か一冊マルチスレッドの本読むのおすすめする

510:デフォルトの名無しさん
09/04/05 04:12:53
class Hoge{
public:
 void End(){
 /*他のスレッド、シグナルハンドラとかから呼ばれる */
 Lock_.GetLock(); // 実際はRAII使ってるよ
 continuable_ = false;
 //その他のリソース会報処理
 }

 void Task(){
 // thread poolから実行されるタスク。
 Lock_.GetLock();
 if( continuable_ == false ){ return; }
 // IO処理とか色々非同期でやる
 }
};

なんか、フラグ使ってやるのが嫌なんだけど、
非同期で実行されるオペレーションをキャンセルさせる
スマートな方法ってない他にない?
この実装は間違ってる?

511:デフォルトの名無しさん
09/04/05 11:59:52
いいんじゃねえの。
スレッドを自発的に終了させるには
スレッド自身が何かをチェックしなけりゃならんし。

512:デフォルトの名無しさん
09/04/05 13:17:02
間違ってないし、フラグを使う方法は普通によくある

513:デフォルトの名無しさん
09/04/05 19:31:13
別プロセスにしてkill -9、これが最強。

514:デフォルトの名無しさん
09/04/05 19:36:59
せめてSIGTERMでやんわり殺してやれよ。

515:デフォルトの名無しさん
09/04/06 12:50:48
そうそう、せめて覚悟する時間くらいは与えてあげないと。
尤も、そうすると逆切れして殺しに来るかも試練が。

516:デフォルトの名無しさん
09/04/09 00:33:31
変数か構造体かクラスのインスタンスa,b,c,dがあるとして、
まず、スレッド1がaとbを使用、スレッド2がc,dを使用する。
その後、スレッド間通信とかでスレッド1も2も上のa,b,c,dを使用した処理が完了したことをスレッド1,2に伝える。
そして、スレッド1がa,cを使用、スレッド2がb,dを使用する。
といったような処理をするときに、特別にロックとか必要ですか。

517:デフォルトの名無しさん
09/04/09 00:58:51
>その後、スレッド間通信とかでスレッド1も2も上のa,b,c,dを使用した処理が完了したことをスレッド1,2に伝える。
これで同期取ってるから、そこをちゃんとすればよい。

518:デフォルトの名無しさん
09/04/09 01:47:33
弱い順序付けの場合だめな場合がありえるかもね

519:デフォルトの名無しさん
09/04/09 17:49:21
ねーよw

520:デフォルトの名無しさん
09/04/09 19:12:35
>>518
お前にとって同期ってなんだ?

521:デフォルトの名無しさん
09/04/09 19:52:20
グローバル変数keyに対して、他のスレッドで値を変更してループの続行、終了を決める場合に
while ( key ){ count++; }
というコード書くとコンパイラの最適化によって、無限ループになる可能性があるということですが、
while ( *pk ){ count++; }
のようにアドレスから参照しようとしても同じことになるのでしょうか。

522:デフォルトの名無しさん
09/04/09 20:54:12
わかんない。

つーか key を volatile にすりゃいいんでない?

523:デフォルトの名無しさん
09/04/09 21:01:11
>>521
うん。十分ありえる。

524:デフォルトの名無しさん
09/04/09 21:07:43
volatileで大丈夫そうですね。ありがとうございました。

525:デフォルトの名無しさん
09/04/12 11:51:26
マルチスレッドがどういうタイミングで割り込まれるのかわからないのですが
たとえば、if(++i == n) のコードなら
iをインクリメントしてからnを比較するまでの間で
割り込まれる可能性はあるんでしょうか?

526:デフォルトの名無しさん
09/04/12 12:30:10
あるよ
そもそも正しくインクリメントされることも保証されない
(CPUやコンパイル出力によるけど)

なぜなら、
(1) メモリからiの値を読み出す
(2) 値+1を計算する
(3) iの領域に計算結果を書き込む
という3ステップになる可能性があるから

527:デフォルトの名無しさん
09/04/12 12:43:39
>>526
そのステップ間で割り込まれるんですか、結構分割されるものなんですね
ありがとうございました

528:デフォルトの名無しさん
09/04/12 14:33:39
>>527
ただし、いつもそのように分割されるとは限らない。

529:デフォルトの名無しさん
09/04/13 22:54:34
volatile最強杉www

530:デフォルトの名無しさん
09/04/14 10:18:14
fread等でのデータ読み込みをシングルスレッドで実行する場合と
マルチスレッドで実行し、メインスレッドでは出来るだけ何もしない場合の速度は同程度になるものでしょうか?

531:デフォルトの名無しさん
09/04/14 10:27:26
>>530
速度は実測が基本。

たぶんその比較内容だと、激しく環境(ハードウェア、OS、コンパイラ)に依存する。

532:530
09/04/14 10:57:26
WindowsXP、vc2003、C2D E7200です。
timeGetTimeで測定した所、
マルチスレッド側の速度が安定しないのですが、
100kb程度のデータで2倍、1mb程度だと4割程度の速度差になりました

メインスレッドは以下のようなループになっていています
while(1){
 if(PeekMessage(&msg,0,0,0,PM_NOREMOVE)){
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 } else {
  // メインスレッド

 }
}

533:デフォルトの名無しさん
09/04/14 11:00:25
色々条件がよく判らんが、ここが一番判らん。
>100kb程度のデータで2倍、1mb程度だと4割程度の速度差になりました
2倍の速度差と4割の速度差ってどういう意味なんだか。
シングルスレッドに対してマルチスレッド版は2倍の速度差、つまり3倍所要時間が掛かったのか?

534:530
09/04/14 11:11:23
すみません、
所要時間
    シングル マルチ
100kb 0.013秒  0.025秒
1mb  0.100秒  0.140秒

です

535:デフォルトの名無しさん
09/04/14 11:17:22
>>530
マルチスレッドは、複数のことを同時にしたいときに使う技術なので、
そういう視点で選択した方がいいですよ。

ただ速度といっても、プライマリスレッドからストレージアクセスを
しているときキャンセルボタンを押したいんだけどその反応が鈍い、とか、
ストレージをアクセスしながらムービーを表示しているのだけれどコマ落ちする、とか、
単純コピーを速くしたい、では、とるべき手段に違いがありすぎます。

単にあるデータをストレージから読み込む処理だけに着目するなら、シンプルな
シングルスレッドの方が高速になることが多いと思います。
予め別のスレッドで利用するファイルを予測してアクセスし、キャッシュに入れておく
などというのはまた別の問題ですが。

536:530
09/04/14 11:33:30
>>535
ありがとうございます
極力シングルで動作できるような方法考えることにします

537:デフォルトの名無しさん
09/04/19 14:10:04
>>435
Phenomの2コアで2スレッド動かしたら2.2倍以上のスコアを叩き出した。
確かに2倍になる訳じゃないね。但し、配列をL2とL3に合わせて巧く分割
できた場合に限るけど。あと、OSのや他プロセスのボトルネックがある分
やっぱりマルチコアの方が早いね。実質90%でしか動けないシングルは倍
にしても180%だけど、90%+100%で動けるマルチコアだと実質190%で10%
ぐらい早くなる。

538:デフォルトの名無しさん
09/04/19 14:41:22
>>521
別にvolatile使わなくても問題なくね?
static int key=1;
void Thread0()
{
 key=0;//volatile指定が無い場合消失する可能性がある。
 Sleep(100);
 key=1;
}
void Thread1()
{
  while ( key ){ count++; }
}
こんな事でもしない限り無限ループにならんべや。
こんなコード書くことまず無いだろ。

それと、そもそも、グローバル変数使うなよ。

539:デフォルトの名無しさん
09/04/19 19:33:59
>>538
バカでしょ

540:デフォルトの名無しさん
09/04/19 22:08:19
>>538
まず、ネタなのかマジなのかを書いてくれ。

541:デフォルトの名無しさん
09/04/19 22:25:33
>>538
バカなの?死ぬの?

542:デフォルトの名無しさん
09/04/19 22:53:09
>>539-541
まじか。何で?

543:デフォルトの名無しさん
09/04/19 23:02:48
volatileを使うと排他制御しなくて
よくなるから必要

544:デフォルトの名無しさん
09/04/19 23:19:55
それは誤り

545:デフォルトの名無しさん
09/04/19 23:50:48
keyをテストする所にメモリバリア入れないと駄目じゃないかね

546:デフォルトの名無しさん
09/04/20 01:29:15
例えばJavaやC#などだと参照してる変数がvolatileだと期待通りに動くが、
そうじゃないとどうなるか分からんのじゃない?


547:デフォルトの名無しさん
09/04/20 15:54:13
>>543
volatileと排他制御はなんの関係もないぞ。
volatileは最適化の抑止で、せいぜい>>538の様な事や
レジスタだけでなくメモリ側にも変数を割り当てるぐらいだ。
そもそも、CやC++に排他制御なんて概念は無いから
クリティカルセクションなんかを使う他無い。
ちなみに、Javaは排他制御がかかるが、グローバル変数
と言っているからCかC++だ。もしかして、間違えてないか?

548:デフォルトの名無しさん
09/04/20 16:04:59
 で、>>539-541は、人をバカ呼ばわりしただけの
まっとうな理由あるんでしょうねぇ。まさか、Javaや
C#のvolatileしか知らない癖にバカにしてたなんて
恥ずかしい理由じゃありませんよねぇ当然。

549:デフォルトの名無しさん
09/04/20 16:23:18

J

550:デフォルトの名無しさん
09/04/20 19:35:31
【OS】WindowsXP SP3
【言語】C
ソース URLリンク(f50.aaa.livedoor.jp)
↑をcygwinでコンパイルすると
In function `thread_func':
14: warning: assignment makes integer from pointer without a cast
In function `main':
54: warning: passing arg 3 of `pthread_create' from incompatible pointer type
というエラーが出ます。
14行目と54行目が悪いことはわかりますが具体的な原因がわかりません。
ちなみにexeファイルは生成されます。

よろしくお願いします。

551:デフォルトの名無しさん
09/04/20 20:32:51
>>550
4: warning: assignment makes integer from pointer without a cast
In function `main':
キャスト無しじゃ整数をポインタにできないっていうような事書いてあるね。

pthreadのプロトタイプはこんな感じで第3引数には関数ポインタを、第4引数にはvoidポインタを取るように
なってる?
int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);

君のコードだといずれもdoubleにキャストしているけど何故だい?
pthread_create(&a[i], NULL, (double *)thread_func, (double *)array);

※スレッドなんて飛躍したものに手を出す前にこの手のエラーを自己解決できる
程度には言語機能を勉強し直した方がいい。

552:デフォルトの名無しさん
09/04/20 20:41:56
>>550
んだんだ、
それに、Cなんだから、void * が絡むときはキャストしない方が
素直で、読みやすいコードになる。
たとえば、
double *data = (double *) arg;
は、
double *data = arg;
としろ、ってことね。C++から来た人はこれをやりたがるのね。
C++だとこの場合にもキャストが必要だから。

乱文澄まそ

553:デフォルトの名無しさん
09/04/21 01:49:59
>>551
pthread_create(&a[i], NULL, (double *)thread_func, (double *)array);
は単に見落としていたようです。
お手数掛けて申し訳ないです。
直したらこの行のエラーは出なくなりました。

>>552
C++をやっていたわけではないのですが、配布されたソースコードの例にはこの形で書かれていたのでそれに準じて書きました。

そしてまだ14行目でエラーが出ますがpthread_selfの扱い方はそもそもこれでよいのでしょうか?
ちょろっと調べて出てきたものを使っただけなのでよく理解していません。

554:553
09/04/21 02:06:23
すみません、調べたらわかりました。
ただし他の問題が浮上しました。
pthread_t型をint型か何かに変換できないんですかね・・・。

555:デフォルトの名無しさん
09/04/21 02:31:33
>>554
pthread_tはポインタか構造体かなんかでしょ。
そもそも、別の型に代入しちゃいけない。
語のライブラリだと結構やろうと思えば別の型
に無理やり代入する事も出きるけどしちゃいけない、
内部に干渉しちゃいけないものがある。
大体識別値(discriptor)と呼ばれるものなんかがそう。
あと、初心者の内はメモリ操作が簡単にできる事が解って乱用する
人がいるがポインタのキャストはやたらめったらつかうもんじゃない。

てか、君の悩みはスレッド以前の問題だから、Cの初心者スレなんか
で質問しなさい。




556:デフォルトの名無しさん
09/04/21 20:37:55
言い方は気にくわないなw
小さい芽潰して楽しんでるふうにしかみえねーよ老害

>>554
pthread_tはunsinged longのtypedefだよ


557:デフォルトの名無しさん
09/04/21 21:56:02
>>556
何を言ってるんだおまえは? >>550のwarningを100回読み直してから出直してこい

558:デフォルトの名無しさん
09/04/22 00:05:38
>小さい芽潰して楽しんでるふうにしかみえねーよ老害
ふーん
芽をつぶして楽しんでて害なんだ
ふーん


559:デフォルトの名無しさん
09/04/22 01:49:54
そうなんじゃね、多分。

560:デフォルトの名無しさん
09/04/22 02:46:06
大人なんだからもっと仲良くしろよ

561:デフォルトの名無しさん
09/04/22 21:38:45
歯痛制御で俺の虫歯を何とかしてくれ

562:デフォルトの名無しさん
09/04/22 22:28:22
チュイーン ギキィィーー

563:555
09/04/22 22:56:29
>>556
 俺、21歳なんだが。3D関連でC++始めて5年以上にはなるが、
そうか俺も、もう老害か・・・。

564:デフォルトの名無しさん
09/04/23 00:01:02
>>561
本業歯医者の趣味グラマだけど何か用?

565:デフォルトの名無しさん
09/04/23 02:10:25
>>564
医者の趣味グラマっておおいな。
LHAも医者だし猫プロの筆者も医者。
しかも、本業より優秀そうなんだよな・・・。

566:デフォルトの名無しさん
09/04/23 02:33:52
本当は工学系にいきたかったのに、
なまじっか頭いいと医療系への進学を勧められちゃう奴って多いからな

567:デフォルトの名無しさん
09/04/23 09:19:51
いつも思うんだけど、歯科治療技術も日々発展してるだろうから
古い医者より新しいところの方がいいのかねえ

568:デフォルトの名無しさん
09/04/23 11:19:32
ジャストシステムのスタートアップにも医学生がいたな。
人間って本当に不公平にできてるよ。

569:デフォルトの名無しさん
09/04/23 12:48:15
>>564
予約時間の十分前には歯科に着いているのに
待合室で一時間待たされ、診察室に通されたと思ったら
また三十分以上待たされるのを何とかしてくれ

どう見ても歯科医と歯科助手がデッドロックを起こしているようでなかなか回ってこない

570:デフォルトの名無しさん
09/04/23 19:35:34
>>569
誰がうまいこと言えとw
デッドロックは言いえて妙だったわ。

571:デフォルトの名無しさん
09/04/23 23:58:32
>>567
少なくとも、レントゲン撮影したら「現像するから日を改めて」なんてところは止めた方がいい。
今時、治療椅子ごとに端末があってそこで見られるのが当たり前。

572:デフォルトの名無しさん
09/04/24 09:00:21
>>571
端末は無いけど、数分で現像したフィルムができるのが普通じゃない?
2,30年前からそうだったと思うんだけど

573:デフォルトの名無しさん
09/04/24 09:44:28
いい加減にしとけよ

574:デフォルトの名無しさん
09/04/24 11:57:45
マルチスレッドと減増
関係あっても、遠い存在のような


575:デフォルトの名無しさん
09/04/24 17:51:20
>>556
老害ではなく、基地害だ


576:デフォルトの名無しさん
09/05/02 22:30:20
俺の日記帳
今日は5月2日です。
何してるの?

577:デフォルトの名無しさん
09/05/04 23:25:22
C++0xではマルチスレッドプログラムを組むのは
容易になるのであろうか

578:デフォルトの名無しさん
09/05/04 23:26:23
C++でマルチスレッドは危険ですよ

579:デフォルトの名無しさん
09/05/04 23:36:49
>>578
Win32本では平気でマルチスレッド走らせる例が書いてあるけど
デッドロックについても詳しく説明してある

580:デフォルトの名無しさん
09/05/05 04:20:22
>>579
なんだその会話になってないレスは

581:デフォルトの名無しさん
09/05/05 06:50:37
CやC++の言語レベルではマルチスレッドについての取り決めはない。
ライブラリ(pthreadなど)やプラットフォーム(osやハードウェア)や実装(コンパイラ)レベルで、
扱いが決められているので、そういったものの前提抜きでマルチスレッドは語れない。

582:デフォルトの名無しさん
09/05/05 09:33:35
メモリモデルの仮定が入っちゃうからやりにくいだろうなあ

583:デフォルトの名無しさん
09/05/05 09:58:42
>577
concurrency 周りが大幅に強化されてるんで、恐らくは。

584:デフォルトの名無しさん
09/05/09 12:04:34
マルチスレッドにする利点は何?
複数の処理を同時に走らせることができるなんて妄想は無しで。

585:デフォルトの名無しさん
09/05/09 12:10:53
世界の全てが妄想なので、答えは消滅しました。

586:デフォルトの名無しさん
09/05/09 12:12:54
複数の処理を同時に走らせることができる、妄想で無しに。

587:デフォルトの名無しさん
09/05/09 13:11:27
個人的には>>584が何故「複数の処理を同時に走らせることができる」ことが妄想だなんて妄想を抱いたのか知りたい希ガス。
マルチスレッドの利点は全てそこから派生しているはずなのだが。

588:デフォルトの名無しさん
09/05/09 13:25:02
>>587
TSSは同時ではないとでも言いたいんじゃないか?

589:デフォルトの名無しさん
09/05/09 15:05:51
>複数の処理を同時に走らせることができる
ってのはいわゆる手段なんで。
大元の目的は「暇をもてあましてるリソースを有効活用する」だな。
マルチスレッドはCPUがヒマしてる場合の、GPGPUはGPUがヒマしてる場合の手段だな。

>584がどんな妄想してるか迄はわからんが。


590:デフォルトの名無しさん
09/05/09 15:53:09
>>589
それ以外にもあるぞ。むしろプログラマ的にいちばんうれしいのは、コンテキストの異なる処理を明示的な切り替え無しに同居させられることじゃなかろうか。
重い処理を別スレッドでガリガリ処理しつつ、その進行状況をGUIで表示するとか。

591:デフォルトの名無しさん
09/05/09 23:10:29
ハァ?
すべてをファイル・デバイスにしてそれをpollすればシングルスレッドで可能ですが何か?

592:デフォルトの名無しさん
09/05/09 23:20:27
スレタイ無視

593:デフォルトの名無しさん
09/05/09 23:39:00
昔のunixはスレッドなしでもfork/execだけでたいていの事はやれてたな。

594:デフォルトの名無しさん
09/05/10 05:27:53
>>591
ちょっと話違うが、Androidのセンサーまわりの設計もそんな感じ。
だが、そのファイルディスクリプタをもらう元が、1つしかなかったり
してセンサーごとにドライバが作れない。

1.0のころはモジュール化すらされてなかったり、1.5になっても
いまだダセー設計だし。設計したやつの顔が見たいな。

595:デフォルトの名無しさん
09/05/10 08:32:10
ドライバといった低レベルI/O処理の基本はスレッドより割り込み。
割り込みがないディバイスだとポーリングも使うけど。

596:デフォルトの名無しさん
09/05/10 09:07:05
何かの処理で待ちも含めてぐるぐる回りながら、他の処理も同時にやりたい、とかいう場合に
いちいち処理を細切れにしてpollを含むメインループから呼び出す形に縛られるのは面倒だわな。

マジレスすると。

597:デフォルトの名無しさん
09/05/10 10:29:43
>>593
でも今はマルチスレッドがサポートされているということは、その煩雑な方式では力不足だったってことだよね。

598:デフォルトの名無しさん
09/05/10 10:51:01
今のところは、
やることを細切れにできるようにしておいて
pollするスレッド(大半の時間は待機)が
少数のワーカーに仕事を振り分け
ワーカーはひたすら仕事だけを待ちつづける、というやり方が
I/O待ちやマルチCPU(コア)を有効に生かせ、
メモリやコンテキストスイッチのロスも少なく出来ると言われてるな。

599:デフォルトの名無しさん
09/05/10 10:56:07
開発効率という効率を無視すれば、それがベストだねw

600:デフォルトの名無しさん
09/05/10 13:17:08
OSのスケジューラをエミュレートしてるだけのような

601:デフォルトの名無しさん
09/05/10 15:04:43
コア数を大幅に越えるスレッドを生成すると、
コンテキストスイッチのせいでむしろ性能が低下する。ってのは本当なの?
実測して確かめたいんだけど、どういうコードを書けばいいのか解らん。
えろいひと教えて

602:デフォルトの名無しさん
09/05/10 15:07:34
スレッドプールにすりゃ解決よ

603:デフォルトの名無しさん
09/05/10 15:11:52
>>601
本当
スレッドに手を出した頃それに嵌ったことがある
各スレッドの同期にmutex/conditionを使う形で大量のスレッド作って試してみればわかるよ
むやみにスレッド数を多くするのはそもそも設計が良くないです

604:デフォルトの名無しさん
09/05/10 16:01:38
オーバーヘッドが増大する。 スレッドの多さは関係無し。 
たとえば1ms以内で終了するスレッドを生成すれば効率悪い。

605:デフォルトの名無しさん
09/05/10 16:02:56
>>601
スレッドって、一般にはコンテキストスイッチが入らない
(だから軽い)というモノだろう?

原理的には性能低下は無い。
但し、実際のところコア間でキャッシュを共有してたり、
メモリバスを共有してるので、複数のコアを同時に使うことで
シングルコアよりも性能低下することはありうる。


606:デフォルトの名無しさん
09/05/10 16:22:26
マルチスレッドのプログラム組んでるんでて
ある変数に複数のスレッドから同時にアクセスできるときは
排他的処理しないとだめ?
というか たぶん今のエラーはそうだろうと思う

607:デフォルトの名無しさん
09/05/10 16:24:10
複数スレッドからアクセスしても、OSがエラーはいたことはないな。
値は、ぶっ壊れるけどね。

608:デフォルトの名無しさん
09/05/10 16:28:00
読むだけなら問題ない

609:デフォルトの名無しさん
09/05/10 16:29:54
読み書きしても、エラーでたことない。 
たとえばグローバルsum=0に、複数スレッドから足し算してもエラーで停止しないが。

610:デフォルトの名無しさん
09/05/10 16:31:49
どういった場合に、メモリーエラーが起こるのかが知りたい。

611:デフォルトの名無しさん
09/05/10 16:33:36
>>605
> スレッドって、一般にはコンテキストスイッチが入らない

今コンキストスイッチしないのって絶滅危惧種だろ

612:デフォルトの名無しさん
09/05/10 16:36:05
なるほど
変数がスタックで削除したり追加したりだからダメなのか

613:デフォルトの名無しさん
09/05/10 18:23:53
>>605
マテ、スレッドでもコンテキストスイッチは発生するぞ。
スレッドが(プロセスに比べて)軽いのは、スタックとレジスタだけ
切り替えれば済む(これもコンテキストの切り替えだ)からであって、
コンテキストスイッチそのものが行われないからじゃない。

614:デフォルトの名無しさん
09/05/10 18:26:42
1CPUの場合はタイムスライスだけになるから減らないが、
CPUが複数ならスイッチ自体を減らせるという話じゃないかい。


615:デフォルトの名無しさん
09/05/10 22:05:51
>>613
ユーザランドでのスレッド実装だと
カーネルモードに入る回数が少なくて済むとかじゃね?

というかこの手のは、何が重いか時代により激しく違ってくるから
一般論といってもそれが何時のものかによるなあ

616:デフォルトの名無しさん
09/05/11 21:55:27
昔を語るのが一般とは思えない。

617:601
09/05/11 22:46:47
時代によって変わるもんなのか。
レジスタ、スタックの退避とか、カーネルに入って出てくる処理とかが重いのかとかとか思ってたんだけど。
fiberは軽いよ。とか聞くけど、それはおいといて。
>>603
mutexとか排他は考えないで、純粋に「コンテキストスイッチ」処理がどれくらい重いもんなのか
図りたい。
linuxでpthread使ってやろうと思ってるんだけど、どんなコードを書けばいいんだろ
単純に0から0xffffffffまで足す処理をシングルスレッドでやるか、
0~0xffを足す処理を0x1010101個のスレッド立てて計算させて、どっちが早いか。とか?<そりゃないだろって

618:デフォルトの名無しさん
09/05/11 22:57:13
>>617
CPUの数だけ分割するのが速い

619:デフォルトの名無しさん
09/05/11 23:28:58
例えば
20ms(OS次第)以上かかる計算処理を一つのJobとして
Job計10000個をキューに入れる。
スレッドをプールしておいて、各スレッドはキューからJobを取り出してひたすら実行する。
この時、プールするスレッド数をプロセッサ数と同数の場合と2000個の場合とで実行時間を計る。

現実的には、スタック領域以外にも
各スレッドで多少の独立したメモリ領域は使うことが多いと思われるので
ただの(レジスタやスタックで納まる)計算はではなく、
16Kなり64Kなりの領域をスレッド毎に確保しておいて
その内部の値を使った計算とする。

等というのはどうだろうか。

620:デフォルトの名無しさん
09/05/11 23:39:02
別にキューに入れる必要無いな。
同じことを繰り返すだけなんだから、CASを使ったカウントアップだけして
一定の数字になったらスレッド終了で充分か。
これなら、共有メモリを使えば、プロセスとの比較も出来る。

ただ、スレッドは「スタートのシグナル」を全部同時に出すことが出来るけど
プロセスだとどうなんだろ。全然知らない。

621:デフォルトの名無しさん
09/05/21 21:54:47
昔はPVM、今の時代はMPI
そしてOpenMPとMPIのハイブリッド実行が主流なのだろうか

622:デフォルトの名無しさん
09/05/21 22:39:20
>同じことを繰り返すだけなんだから、CASを使ったカウントアップだけして
>一定の数字になったらスレッド終了で充分か。

こんな非現実的な処理の時間を計測して何の意味があるわけ?


623:デフォルトの名無しさん
09/05/21 22:40:10
おそらくプロセッサ(コア)が増えれば増えるほど遅くなると思うけど。


624:デフォルトの名無しさん
09/05/21 22:44:10
ああ読み違えてたすまんのう
単に処理繰り返し数のカウントで使うだけってことね…


625:デフォルトの名無しさん
09/05/21 23:23:37
VC(VisualStudio2005)でコーディングしております。

「g_hThread = (HANDLE)_beginthreadex(NULL,0,MainLoop,0,0,&g_dwThreadId)」
で、スレッドを生成し、そちらで、

if(GetAsyncKeyState(VK_UP)&0x8000)

ではキーが取得できるのに、

GetKeyboardState(diks)
if(diks[VK_UP] & 0x80)

ではキーが取得できません。
どうも、メッセージキューやらが原因みたいですが、理屈がイマイチわかりません。
解決策や問題点など、教えていただけると幸いです

626:626
09/05/22 00:14:01
追記です。

そもそもGetKeyboardState()はメッセージキューに溜まったものを見るものであって、
新しく生成したスレッドでは、肝心のメッセージを取得することができない、、、
というあたりまではなんとなく理解できました

ちなみにやりたいことはキー情報の一括取得(できればリアルタイムの)です。
(GetAsyncKeyState()では1つ1つしか取れないので・・・
引き続き、解決策などありましたら、お願いします

627:626
09/05/22 01:06:46
生成したスレッドの方で、

// Threadのインプットのアタッチ
int targetThread, selfThread;
targetThread = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
selfThread = GetCurrentThreadId();
AttachThreadInput(selfThread, targetThread, TRUE );

/*===== メインループ =====*/

// Threadを切り離す
AttachThreadInput(selfThread, targetThread, FALSE );

とすれば、GetKeyboardState()でも一応取得できました。
荒療治な気がしますが・・・
もっと良い方法などありましたら、お願いします

628: ◆0uxK91AxII
09/05/22 02:41:05
>>617
適当なsystemcallを行い、前後でCPUのtimestampでも読めば、
最も軽い場合については、調べられる。

>>625
DirectInputを使うとか。

629:デフォルトの名無しさん
09/05/22 03:20:02
>>627
GetKeyboardState()が使用する入力情報は、スレッドごとにある。
AttachThreadInput()はそれを共有させるためのAPIなので、その目的なら
それが一番適切な方法。
ただ、フォアグラウンドウインドウにAttachしてるのは間違いじゃないか?

GetAsyncKeyState()は自分のプロセスが非アクティブでもキー情報を取得できるAPI。
自プロセスの別スレッドでキー入力を拾う目的で使うのは、使えないことはないが
自分がアクティブかどうかの確認が必要で面倒。

630:626
09/05/22 04:59:32
>>628
DirectInputは同じような理由で取得できず...(・ω・

>>629
問題なく動いてるんで今の形(フォアグラウンド)で放置してたんですが、
ウインドウハンドルって引数以外で取得できるんでしょうか

631:デフォルトの名無しさん
09/05/22 06:02:44
>>630
GetWindowThreadProcessIdもGetForegroundWindowもいらない。
beginthreadexを呼んだスレッドで、そのままAttachするだけ。

そもそも、自分のウインドウを取得するのにGetForegroundWindowを
使うこと自体おかしい。
アプリケーションを起動したら必ずフォアグラウンドになるわけではないし。

632:626
09/05/22 15:13:54
確かにかなり回りくどいことしてました。

ただ、Attachの処理は生成処理の直下で一度だけ呼び出しても機能しなかったので、
beginthreadexを呼んだスレッドID(MainThreadId)だけをセーブして、
>>627と同じ場所で「AttachThreadInput(CurrentThreadId, MainThreadId, TRUE );」という形にまとめました。

633:デフォルトの名無しさん
09/05/22 16:18:42
新しく作成されたスレッドはGUI関連のAPIを呼び出すまでメッセージキュー等が
作成されないから、スレッド作成直後だと失敗するね。

新しいスレッドでウインドウを持っているならウインドウ作成後、ウインドウが
なければPeekMessageの空呼び出しの後でAttachがいいかな。

634:???
09/05/22 16:58:17
アセンブリ言語によるプログラミングで、1+2+3+・・・・+10と、1から10までの足し算をするプログラムはどのようなものになりますか?

16進数表現です。

635:デフォルトの名無しさん
09/05/22 17:14:22
まずは正しいスレッドを探すことからだな

636:デフォルトの名無しさん
09/06/09 21:56:35
質問です。

constで定義されている、読み込み専用の変数に対して
複数のスレッドがアクセスするとき、同期(クリティカルセクションなど)は
必要ありますか?

637:デフォルトの名無しさん
09/06/10 07:47:41
よっぽど変なハードウェアでない限り
要りません。

638:デフォルトの名無しさん
09/06/10 19:52:05
volatileで十分w

639:デフォルトの名無しさん
09/06/13 18:02:44
volatile使うやつは情弱

640:デフォルトの名無しさん
09/06/26 02:20:50
WindowsXP、VC2008EEの環境で作っています。
>>636の質問とかぶるのですが、1つのコンテナを複数のスレッドからイテレータでアクセス(読み込みのみで書き込みはない)しています。
実行時にイテレータを使った部分(直接使用しているのはSTL)でエラーが出て強制終了になってしまいます。
試しにスレッドを1つにしたらエラーは出ませんでした。
どういった原因が考えられるでしょうか?

641:デフォルトの名無しさん
09/06/26 03:48:25
そのSTL実装がスレッドセーフじゃないんでしょ。
機能としての読み込みであっても、内部で書き込みしていて競合する場合もあるだろう。
アトミックなところまでスレッドセーフが保証できないならロックすべき。

642:デフォルトの名無しさん
09/06/26 04:59:50
>>641
なるほど・・。
マルチスレッドは難しいですね。

643:デフォルトの名無しさん
09/07/04 11:06:03
>>640
単純に興味本位なんだが、const_iterator でも駄目なの?

644:デフォルトの名無しさん
09/07/04 11:09:45
最近マルチスレッド環境下でスレッド毎にプールを持つ
malloc() 実装がよくあるよね? 諸々の事情でそれが使
えない場合、アプリ側で出来る事ってある?

OO 的に小さなオブジェクトを生成/破棄するんだけど、
スレッドを跨って破棄を委譲するケースもあるんだ。で
も、単純にメモリ管理スレッド作っても過去の効率の悪
い malloc() 実装の焼き直しみたいになって多分効率悪
いと思うんだよね…。

645:デフォルトの名無しさん
09/07/04 11:16:05
アプリ側でそういう実装をやってるのはあっても動作環境側でそんな実装やってるの在るか?
複数のプール持つ実装はあるだろうけどスレッド固有になるような実装してたらそれこそスレッド跨げないし

646:デフォルトの名無しさん
09/07/04 11:49:37
>>645
ああ、中央ヒープはあるんだよ。でも、スレッド毎にも
管理されるよね? 多分細かくスレッドが生成/破棄され
るようなケースではかなり改善されるんだと思う。

URLリンク(goog-perftools.sourceforge.net)
↑Google の tcmalloc はコアヒープとスレッド毎のキャッ
シュという形で実装されている。

URLリンク(people.freebsd.org)
↑FreeBSd の jemalloc もスレッド毎に管理されてるみ
たい(TLS)だけど、要求されるサイズによって割り当て
部を買えるような話がある。

でも、やっぱりスレッド跨ると古い malloc() と同じ話?
うーん、ここまで来ると「どのコアで動くか」まで関連
するかなぁ…。

647:デフォルトの名無しさん
09/07/04 12:19:54
jemallocは自分が割り当てられたarenaをヒープのメタデータにつっこんでおいてfree時にはそこから解放するようになってる
割り当てはそれこそぽんぽん次のarenaをTLDに結ぶけどさ
そうでもしなきゃFreeBSDのデフォルトになれてない

完全に一切ロックせずスレッド固有のヒープにするなんてのはアプリ内の実装でなきゃ出来んよ

648:デフォルトの名無しさん
09/07/04 12:35:06
いやだからそのアプロ側でどうすんの? ってのを聞いてるわけで…。

649:デフォルトの名無しさん
09/07/04 12:43:37
一体何を心配して居るんだお前は?

650:デフォルトの名無しさん
09/07/04 13:46:18
小さいメモリ大量なら、固定長のバッファをリンクリストかなんかに
つないでおいて、利用すればいいじゃん。malloc, freeよか速い
だろ。

651:デフォルトの名無しさん
09/07/04 17:04:33
>>644
mallocにしてはやりすぎじゃない?
C++のallocatorならそういうのもあると思う。

652:デフォルトの名無しさん
09/07/06 15:13:06
とりあえず何も考えず素直に作って問題が出たら詳細に
考えることにするよ。一応アロケータ的なインタフェイ
ス挟んでるから後からでもなんとかなると思う。

malloc/free に時間かかってる/かかってないの判定と
かは gprof 辺りで大丈夫なんだっけ?

653:デフォルトの名無しさん
09/07/07 13:30:13
>>652
一応gprofでも判らなくもないと思う。呼び出し回数は記録されないけどね。
使える環境なら、vtuneみたいなツールを使う方が(当然)判りやすい。

654:デフォルトの名無しさん
09/08/04 10:34:44
pthreadで、デタッチ状態のスレッドをポコポコつくったりしてるとき
生成したスレッドのうち今何個生きているかを知りたいんだけど
pthread_hogehoge() で何か知れるような手段用意されてたっけ?

655:デフォルトの名無しさん
09/08/04 11:52:30
マルスレage

656:デフォルトの名無しさん
09/08/04 12:00:52
無いんじゃない?atomicなカウンタでも使えばいいじゃん。

657:デフォルトの名無しさん
09/08/04 17:07:08
>>656
もしそういうカウンタがもうあるなら再車輪せずに済むかな、と。

658:デフォルトの名無しさん
09/08/04 18:51:12
Linuxの話だけど、この件については他でも同じ
URLリンク(www.yolinux.com)
A thread does not maintain a list of created threads, nor does it know the thread that created it.

スレッド数だけであれば、psでスレッドの情報出すときと同じ方法でできる?

659:デフォルトの名無しさん
09/08/04 21:20:30
>>658
pstreeとかのソース読んだからまあ大体のことはできるんだけど
そうか、管理しないことをウリにしてんのか。仕方ないなぁ。
スレッド管理はOS任せか~。そりゃそうだよなぁ。

660:デフォルトの名無しさん
09/08/09 15:09:11
Javaで複数のインスタンスのAというメソッドに同期をかけたい場合は、
どうすればよいのでしょうか?

661:デフォルトの名無しさん
09/08/09 15:52:00
>>660
同期は(メソッドにかけるものじゃなくて)メソッドが
アクセスするリソース(メモリやディスク)にかけるものだよ。
あと「同期」はスレッド間でイベントの発生待ち&発生通知を
実現する場合に使われる単語。もしもスレッド間で
(メソッドを通した)リソースへのアクセスの競合を避けるのが
目的なら、「排他制御(あるいはロック)」という単語を使うのが適切。

で、質問が(後者の)排他制御を実現する場合に関するもとすれば、
各インスタンスのメソッドAで(アクセスしたいリソースへの)
排他制御を実装するコードを単純に書けばいい、というのがレスになる。

もしも各インスタンスのクラスが同一ではないため、複数クラスで
メソッドのコードを変更するのはプログラム構造が複雑になると
考えているなら、たとえば以下のようなヒントが参考になるかもしれない。

・コールバック機構を利用して並行処理時に発生するバグを防止する
  URLリンク(japan.internet.com)

662:デフォルトの名無しさん
09/08/09 16:02:51
>>661
ご回答ありがとうございます。
プロセス起動時の初期処理用メソッド(DBからマスタを取得し、キャッシュする)に同期をかけたいと思っていました。
お返事どおり、メソッドではなく、リソース(オブジェクト)に対して、ロックをかけるのが正しいですね。
キャッシュクラスをシングルトンで実装し、同期化をさせることにします。

663:デフォルトの名無しさん
09/08/11 00:33:30
メソッドにsynchronizedを付けると、同一インスタンスで1つのスレッドしか実行できないということですか?
複数インスタンスあれば、実行できてしまうのでしょうか?

664:デフォルトの名無しさん
09/08/11 00:50:50
できてしまいます

665:デフォルトの名無しさん
09/08/12 22:09:06
staticメソッドなら大丈夫。
synchronized(Hoge.class) とか

666:デフォルトの名無しさん
09/08/12 22:56:58
>>665
> staticメソッドなら大丈夫。
> synchronized(Hoge.class) とか

そこまで書くならstaticメソッドじゃなくてもいいじゃん

667:デフォルトの名無しさん
09/08/16 00:34:07
マルチスレッド環境でマスタデータをDBからとってきて、HashMapかListなどに持たせるのは
問題ないのでしょうか?
基本的にJavaプロセスを起動している間にマスタデータが変更されることはない環境です。

668:デフォルトの名無しさん
09/08/16 00:34:56
667です。
データを持たせるHashMapかListはクラス変数で持たせたいのですが。

669:デフォルトの名無しさん
09/08/16 00:37:29
情報不足
どういう問題がありえると思ってるんだ?

670:デフォルトの名無しさん
09/08/16 01:02:48
すみません。
HashMapとかListに数千件というマスタ情報を持たせるのがおかしくないのかという点と、
HashMapやListにデータを追加するときはロックをかけますが、データを取得するときは
ロックをかけなくても問題ないかを知りたいです。


671:デフォルトの名無しさん
09/08/16 01:16:29
>>670
ハッシュなんてもんはメモリが許すなら数万件程度は入る事を前提で作るんだが


672:デフォルトの名無しさん
09/08/16 01:37:04
>>670
(すでに別の方法で同期済み等で) 追加と取得が同時には起きないと判っているなら、取得同士の間のロックは不要
追加と取得が同時に起きるかもしれないなら、取得にもロックは必要

673:デフォルトの名無しさん
09/08/16 06:35:50
通信とかどうでもいいから普通にマルチコアに特化したライブラリってないのさ?

674:デフォルトの名無しさん
09/08/16 08:59:53
つintel TBB

675:デフォルトの名無しさん
09/08/16 09:49:44
>>673
スレッド間通信が無くても役に立つマルチスレッドアプリとは何者?

676:デフォルトの名無しさん
09/08/16 21:13:28
ブルートフォースとか

677:デフォルトの名無しさん
09/08/17 10:00:56
>>675
サーバとか

678:デフォルトの名無しさん
09/08/18 12:29:42
pthreadでPSで表示したときのスレッド名を変える方法ってありますか?

679:デフォルトの名無しさん
09/08/20 11:14:51
ないんじゃない?

680:デフォルトの名無しさん
09/08/27 19:59:12
PR_SET_NAMEすればいいんじゃない?

681:デフォルトの名無しさん
09/08/28 15:32:43
Cでマルチスレッドのプログラミングで
ふたつのスレッドの時間的な同期をとって
同時に同じファイルを開くにはどのように書けばよいですか

682:デフォルトの名無しさん
09/08/28 16:04:42
>>681
そんなことできるんですか

683:デフォルトの名無しさん
09/08/28 16:11:59
>>681
その発想はなかった

684:デフォルトの名無しさん
09/08/28 16:12:05
>>680
ありがとう。とても役に立った。

685:682
09/08/28 16:18:17
>>681
2つのスレッドから共通のモジュールを介してファイルにアクセスするようにしてはどうですか
2つのスレッドからは1つのファイルを開いているように見せつつ,
そのアクセス(読み書き)先の実体であるモジュールの中で排他制御するんです

686:デフォルトの名無しさん
09/08/28 17:14:56
対象OSにどういった同期手段が用意されているかによる
どの程度同時性を求めるかにもよるし、それはつまり何のために同時でなきゃならないのかにもよる


687:デフォルトの名無しさん
09/08/28 20:01:11
>>681
日本語の文章がちゃんと書けない人はプログラミングも出来ない。
by 竹内

688:デフォルトの名無しさん
09/08/28 20:10:31
>>686
これ、日本語が致命的に下手なだけで、要点は
ただ排他制御したいってことだろ

689:デフォルトの名無しさん
09/08/28 20:20:01
時間的な同期を取るってんだから、「同時」の意味が違うかもしれんぞ

690:デフォルトの名無しさん
09/08/28 22:58:07
日本語が下手ではなく、
頭の中で思考の同期が取れてないのでは。

691:デフォルトの名無しさん
09/08/29 02:53:56
排他制御しないって意味かもしれんぞ

692:デフォルトの名無しさん
09/08/29 06:04:35
まぁ、>>681がマルチスレッドでプログラミングすべきでないことだけは間違いないな…

693:デフォルトの名無しさん
09/08/29 08:12:32
>>681
同時に開く保証はできない。
「ほぼ同じ頃に開くことができるかもしれない」が限度

694:デフォルトの名無しさん
09/08/29 08:32:21
2スレッドをイベント待ちにしてから、同時に起こすのかと思った。

695:デフォルトの名無しさん
09/08/29 09:00:31
マルチスレッドプログラムでのよくある落とし穴をまとめたサイトってどこかにない?

696:デフォルトの名無しさん
09/08/29 09:36:25
>>695
URLリンク(www.itmedia.co.jp)
まんまのがあるではないか。

>Windowsプログラマーでスレッドをいちども使ったことがない人はいないだろう。

一瞬それはないだろうと思ったがスレッド使わなきゃWindowsのプログラムは作れぬなw

697:デフォルトの名無しさん
09/08/29 11:12:44
シングルはあるよな

698:デフォルトの名無しさん
09/08/29 11:14:07
まぁ「プログラムなんてとりあえず動けばいいや」と考えている奴は大抵マルチスレッド関連でバグ出してハマるしな。

699:デフォルトの名無しさん
09/08/29 11:19:51
>>698
そういうのは未だ救いようがあるが自分の痛さに気づいていない
プログラマーは救いようが無い。

700:696
09/08/29 11:39:02
よく見たらゴミ記事であるな。
参考にしないほうが良い。スマヌ Orz

701:696
09/08/29 11:47:41
ゴミ記事って言うのは酷すぎた。。
前提知識のない初心者が見ると混乱すると言うのが正しい。

702:デフォルトの名無しさん
09/08/29 18:11:28
冒頭の四行くらいで日本語も問題切り分けも怪しく感じたから流し読みしたけど
どうでもよさそうな記事だった

703:デフォルトの名無しさん
09/08/29 21:52:57
シングルトン実装から始まって愚駄ぐだになって終わってると。

704:名無しさん@そうだ選挙に行こう
09/08/30 10:25:00
>>696の記事の二重チェックロックなんだけど

if (_Value == null) {
 lock (ValueLock) {
  if (_Value == null) {
   A temp = new A();
   Thread.MemoryBarrier();
   _Value = temp;
  }
 }
}
Return _Value;

これだと_Valueが更新される前にlockから抜ける可能性ない?
Thread.MemoryBarrier()するのは_Value = temp;の後じゃないの?

705:名無しさん@そうだ選挙に行こう
09/08/30 13:05:55
_Valueの代入はlockの中にあるから、_Valueが更新される前にlockを抜けるわけはない
第2のスレッドがやってきて外側のif(_Value==null)を見たときに、
もし_Valueがまだnullならlockに引っかかるから最初のスレッドが更新を完全に終えるまで待たされるので問題ない (lock/unlock自体がメモリバリアになる)
問題は_Valueがすでにnullでなかった場合、_
Valueは新しいオブジェクトを指しているけれども_Valueの中のフィールドはまだ更新されてない、という事態が起きうる (メモリの書き込み順序は勝手に並び替えられるので)
それを防ぐためにメモリバリアを挟んで、_Valueが更新されるよりも前に_Valueの中身が更新されることを保証している

706:名無しさん@そうだ選挙に行こう
09/08/30 13:28:19
_Valueが更新されるよりも前に_Valueが参照されないことを保証している

707:名無しさん@そうだ選挙に行こう
09/08/30 13:35:51
_Valueへのアクセスは同期されてないから、lock中で_Valueが更新された直後から
他スレッドからAが使えるようになる。
でも

Aの構築
_Valueの更新
Aの構築の結果がAのフィールドに反映される

となる可能性があり、不完全な状態のAが使われる可能性がある。
だからAをnewした後にThread.MemoryBarrier()してから_Valueに代入する。
_Valueへの代入はlockを抜ける段階で保証される。

ということか。
勉強になった、ありがとう。

708:名無しさん@そうだ選挙に行こう
09/08/30 13:39:37
一応はっておく
URLリンク(www.ibm.com)

709:デフォルトの名無しさん
09/09/01 20:32:30
クアッドコアを使った並列処理を
MFCでのマルチスレッドでやろうとしておりますが、
シングルコアのときと同じマルチスレッドのプログラムでも
4つのコアを利用した並列処理になるんでしょうか?


710:デフォルトの名無しさん
09/09/01 20:34:22
なるよ

711:デフォルトの名無しさん
09/09/01 20:38:55
>>710
そうっすか!ならよかったです。

712:デフォルトの名無しさん
09/09/01 21:08:29
erlang

713:デフォルトの名無しさん
09/09/02 00:40:31
>>709
MFCには詳しくないけどシングルコアで問題なく動いてたMTセーフのつもりの
プログラムがマルチコアにもってくと異常動作することはそれなりにあるん
じゃないの?int型への代入・参照を非同期でやってたりするプログラムだと。


714:デフォルトの名無しさん
09/09/02 01:07:14
>>713
何故int? 64bit整数ならわからんでもないけど。

715:デフォルトの名無しさん
09/09/02 01:11:11
つーかそんなことを質問してるわけじゃねーし。
言ってみたかっただけだろ。

716:デフォルトの名無しさん
09/09/02 01:18:05
intでもread-modify-writeはatomicじゃないぞx86は(も)

717:デフォルトの名無しさん
09/09/02 01:18:42
>>709
なる。OSネイティブのスレッドは、明示的に指定しない限り、複数のコアに分散される。
とは言え、排他制御が適切でないと、各コアを有効に利用できないけど。

718:デフォルトの名無しさん
09/09/02 01:27:46
>>716
いや、それだったらそもそもデータ型問わんのでは。

719:デフォルトの名無しさん
09/09/02 01:33:30
いやいや、おまいら、それ以前にそれはスレッドセーフと呼ばないのでは。


720:デフォルトの名無しさん
09/09/02 02:19:59
>>718
64bitなら、と言ってるから、マシンワードならアトミックと思ってるのかなと思った

721:デフォルトの名無しさん
09/09/02 03:38:51
volatile

722:デフォルトの名無しさん
09/09/02 06:06:12
volatileがどうかしたか?

723:デフォルトの名無しさん
09/09/02 09:42:27
vottakle

724:デフォルトの名無しさん
09/09/02 13:14:01
明白な答えが、ここで出せるわけ無いんだから。
あなたが欲しいのは同意なんじゃないの?だから荒れる。

725:デフォルトの名無しさん
09/09/02 13:37:33
>>724
独り言が言いたいだけだ、とかでないなら
最低限アンカーくらい書いたら?

726:デフォルトの名無しさん
09/09/02 13:55:09
>>725
ごめんめっちゃ誤爆

727:デフォルトの名無しさん
09/09/02 13:57:38
        ∧∧
       ヽ(・ω・)/   ズコー
      \(.\ ノ
    、ハ,,、  ̄
     ̄

728:デフォルトの名無しさん
09/09/02 14:27:31
>>696
いまひとつ怪しい記事だな。
だいたい今の.NETじゃ前提が変わりすぎてて、役にたたないどころか害のが多い気がするし。


729:デフォルトの名無しさん
09/09/02 21:22:08
>>720
64bitを持ち出したのは、32bitマシン(あるいは32bitモード)だと、単一の書き込み/読み出しでも競合すると値が壊れる可能性があるから。
(最初の32bitが書き込み前の、次の32bitが書き込み後の値を読み出す可能性がある)
マシンワード以下なら、順序が入れ替わることはあっても値が壊れることはないと思ってるんだけど、それもあてにならない?
あと、x86系だと、ワード境界をまたぐ読み書きがどうなるかがよくわからない。

730:デフォルトの名無しさん
09/09/02 21:40:02
P6以降はキャッシュアラインドなマシンワードのreadやwriteはアトミックだよ
read-modify-writeはLOCK#がassertされないとアトミックじゃないよ
xchg命令は昔からLOCK#がassertされる仕様だからアトミックだよ

コンパイラも含めた挙動はこの辺も参考にするといいよ
URLリンク(msdn.microsoft.com)(VS.85).aspx

731:デフォルトの名無しさん
09/09/02 21:48:23
URLリンク(www.intel.com)
ここの 8.1 LOCKED ATOMIC OPERATIONS を嫁

732:デフォルトの名無しさん
09/09/02 22:01:55
>>729

>マシンワード以下なら、順序が入れ替わることはあっても値が壊れることはないと思ってるんだけど、それもあてにならない?

w

733:デフォルトの名無しさん
09/09/03 00:09:10
The Art of Multiprocessor Programming
糞本だなぁ



734:デフォルトの名無しさん
09/09/03 03:59:45
volatile

735:デフォルトの名無しさん
09/09/03 05:34:09
volatile変数へのアクセスのアトミック性は、non-volatileな変数へのアクセスと同じ
だから、この流れにvolatileは何の関係も無いよ

736:デフォルトの名無しさん
09/09/03 09:27:34
>>706
読み取り側ではメモリバリアはいらないの?


737:デフォルトの名無しさん
09/09/03 10:14:24
_Valueの値を読み込む前にその指す先の値を読み込むのは不可能だから
メモリバリアがなくても読み込み順序は入れ替わらないはずで要らない・・・んじゃないかなたぶん

738:デフォルトの名無しさん
09/09/03 15:09:34
>>737
>_Valueの値を読み込む前にその指す先の値を読み込むのは不可能だから
>メモリバリアがなくても読み込み順序は入れ替わらないはずで要らない
それが成り立たないアーキテクチャもあるんだな。
URLリンク(www.cs.umd.edu)

739:デフォルトの名無しさん
09/09/03 15:31:35
volatileの話をするときは、C/C++なのかJava/C#(CLI)なのかをはっきりさせろ。
それぞれのvolatileの意味はまるっきり別なんだからな。

740:デフォルトの名無しさん
09/09/03 15:59:30
そうか、やっぱりだめか
例の記事は今見直したらvolatileが付いてるな
なるほど

741:デフォルトの名無しさん
09/09/03 16:18:16
それはメモりバリアかvolatileどっちかって話だから意味ないよ

742:デフォルトの名無しさん
09/09/03 16:36:48
そろそろvolatileについて一言いっておくか
URLリンク(d.hatena.ne.jp)

743:デフォルトの名無しさん
09/09/03 22:04:04
C++っていつまでAtomicIntegerとかないわけ?
ふざけてないか?いい加減にしろ

744:デフォルトの名無しさん
09/09/03 22:06:40
と言われても今年決まる新標準には採用されてるし
一企業や一個人に独占されてる言語と比べるなよ

745:デフォルトの名無しさん
09/09/03 22:10:45
>>744
C++0xは2012年まで延期でしょ
今すごい揉めてるでしょ

746:デフォルトの名無しさん
09/09/03 22:13:31
つーかC++使うならそのくらいはライブラリかAPIか自力で何とかできないと
結局他でつまづく

747:デフォルトの名無しさん
09/09/03 22:23:59
ちょっと来週あたり
C++のatomic実装投下するから誰か100%
厳密に正しいか判断できる人いますか?

748:デフォルトの名無しさん
09/09/03 23:38:00
投下してから聞け。

749:デフォルトの名無しさん
09/09/04 00:20:53
現行C++ + Boost + TBBで組んでおけば、C++0xの時代になっても
スムーズに移行できるんじゃないかな

750:デフォルトの名無しさん
09/09/04 22:04:46
最近はC++の仕事が減ってC#とCばっかりになったお

751:デフォルトの名無しさん
09/09/04 23:55:21
URLリンク(blueroad.sakura.ne.jp)

752:デフォルトの名無しさん
09/09/05 00:54:22
gccだとvolatileは付けても付けなくても
効果ないんだね

753:デフォルトの名無しさん
09/09/05 01:06:06
SomeType() = default;

って奴を普通のC++に直すと
どうやってかけばいいの?

754:デフォルトの名無しさん
09/09/05 01:11:29
>>753
// SomeType() = default;

755:デフォルトの名無しさん
09/09/05 04:53:21
gccでもvolatile付けたら本来のvolatileの効果はあるだろ

756:デフォルトの名無しさん
09/09/05 09:45:20
ちゃんと実装されているマルチスレッドアプリってあるのだろうか。
このスレ見てるとある特定の条件下でたまたま運良く動いているアプリばかりじゃないかと思ってしまう

757:デフォルトの名無しさん
09/09/05 09:50:07
たまたまでもバグが入り込まなかったのならすばらしいことです


758:デフォルトの名無しさん
09/09/05 10:17:49
このスレだけが世界のすべてだと想うなかれ

759:デフォルトの名無しさん
09/09/05 10:20:06
引っ掛かりやすい問題点は多々あるが、ちゃんと分かってくれば安全に書ける
ただ、その「分かってくる」までのハードルがそれなりに高いから、手を出せる開発者
もなかなか増えないし、MTに対応することで恩恵の得られるアプリも少ないから、
MT対応アプリそのものがなかなか増えない訳だが
IntelもMTのフレームワークで金取ってる余裕ねーだろうにと思う(MSあたりは別に
どっちでもいいんだろうが)

760:デフォルトの名無しさん
09/09/05 11:09:19
>>752

const volatile int x;

の説明も出来無さそうだな。


761:デフォルトの名無しさん
09/09/05 11:11:26
ああ、const volatileの意味がすんなり理解できるかどうかはいいテストかもなw

762:デフォルトの名無しさん
09/09/05 11:50:26
それがconst volatile autoな変数なら私には理解できません。

763:デフォルトの名無しさん
09/09/05 12:13:34
C++0xのautoってcvとか*とか&とか付けられるんだろうか

764:デフォルトの名無しさん
09/09/05 12:27:55
>>760
最適化されないRead Onlyな変数以外に何かの意味があるのか?

765:デフォルトの名無しさん
09/09/05 12:29:06
別に最適化されない訳でもないが

766:デフォルトの名無しさん
09/09/05 12:29:18
>>758
日本のマルチスレッドプログラム界の縮図がこのスレだと思っておりますが。

767:デフォルトの名無しさん
09/09/05 12:33:20
ここには「実戦ではまだまだ書けませんが」って人もかなりいると思われ

768:デフォルトの名無しさん
09/09/05 12:39:42
>>767
そういうヤツは時間の問題でちゃんと書けるようになる。
そんな自覚のないヤツほどマルチスレッドを使いたがる。

769:デフォルトの名無しさん
09/09/05 12:40:11
「C/C++の」volatileを誤解してる奴はこれ↓読んどくといいぜ
URLリンク(mkosaki.blog46.fc2.com)

770:デフォルトの名無しさん
09/09/05 13:58:48
マルチスレッドってコンパイラの最適化やCPUの命令の実行順序まで
いちいち気にしていないとまともなプログラムは作れないって事ですか?

771:デフォルトの名無しさん
09/09/05 14:23:36
いいえ
mutexやcondvarの使い方を知っていれば問題ありません

772:デフォルトの名無しさん
09/09/05 14:28:32
mutexは遅いからイヤだ、などと言い出すから話がややこしくなるだけです

773:デフォルトの名無しさん
09/09/05 14:30:03
condvar?

774:デフォルトの名無しさん
09/09/05 14:35:10
条件変数
win32ならイベントオブジェクトか何か・・・・・・特定の出来事を待って寝ているスレッドを起こすメカニズム

775:デフォルトの名無しさん
09/09/05 14:42:17
スレッド間通信そのものがボトルネックになるような場合は、mutexなんか使って
られないから>>770は真に近い
スレッド間通信のコストが無視できる場合は、>>770は偽に近い

776:デフォルトの名無しさん
09/09/05 14:42:37
>>769
そのブログのおっさんって何者なんですか?

777:デフォルトの名無しさん
09/09/05 14:45:40
スレッド管理APIを作る側なら>>770は真

778:デフォルトの名無しさん
09/09/05 16:07:19
>>770
単純に動くものを作りたいなら、そこまでローレイヤーのことを考える必要はない。
が、
プログラムのパフォーマンスを上げたかったりするんだったら、
考える必要が絶対に出てくる。
「まともなプログラム」==「メジャーなソフトウェア」って認識なら、
言う通り、そこまで考えないとまともなプログラムは作れない


779:デフォルトの名無しさん
09/09/05 16:08:26
>>770
適当に作ってはったりかます方が金になるから
きちんとモノ作りする奴は馬鹿を見ると思った方がいいぞ

780:デフォルトの名無しさん
09/09/06 10:56:31
mutexの速度が気になるようなプログラムなんて組んだことないぜ
速度より安定性重視な俺はプロだって周りかよく言われます

781:デフォルトの名無しさん
09/09/06 12:28:25
必要無いならそれでいい
カーネルやドライバを書いてるような連中はそういう訳にはいかない
科学技術計算やゲームエンジンを書いてるような連中もな

782:デフォルトの名無しさん
09/09/06 13:20:16
正しく動くものできっちり金を取った後、
また高速化するたびにきっちり金を取るのはプロだと思う。

783:デフォルトの名無しさん
09/09/06 13:31:25
最初からある程度高速じゃないと金の取れない業種もあるけどな

784:デフォルトの名無しさん
09/09/06 14:14:35
そういうプロが幅を利かせるから日本のIT業界はいつまでたっても土方っていわれるんだろな

785:デフォルトの名無しさん
09/09/06 14:18:37
よく知らんけど海外でもそういう手合いはいるんじゃね?
変に胸張って「俺らこそがプロ」みたいな顔をしてるかは別として
Googleみたいなとこのプロはそういう手合いとは思えないしな

786:デフォルトの名無しさん
09/09/06 16:34:28
>>780に同意する。

いかにmutexの回数やクリティカルセクションの範囲を減らすかに設計能力を注ぐ。
要は、スレッド間の同期を減らし、スレッドの並列度を上げることが目的。
ただし、(>>770の言う)コンパイラの最適化やCPUの実行順序までは考えない。
(>>782の言う)正しく動くものを作ることを最優先する。

マルチスレッディングと、その最適化には、高度に抽象化された思考能力と設計技術が要求される。
(>>778の言う)ローレイヤのことを気にした(言い換えると、ローレイヤの振舞いを前提にした)
スレッディングのロジックを組むということは、プラットフォーム依存な設計であるということ。
(>>781の例であれば)科学技術計算ならUNIXからWindowsへ、ゲームエンジンならPS3からXBoxへ
移植するたびにロジックの再設計が必要になる。

もしかすると自分が知らないだけで、(意図的に?)そういうローレイヤ前提な設計をして、
移植の度に利益を得るという(>>778,779,781のような)世界があるのかもしれない。
ただ、それは(>>784の言う)土方仕事と呼ばれる日本のIT業界の縮図そのものであると思う。

例外があるとすれば、カーネルの、しかもスレッドスケジューラやmutexそのものを実装する
コアなデベロッパに限る。彼らはハード(CPU)の能力を最大限に生かす基盤を作る人達だから。

787:デフォルトの名無しさん
09/09/06 17:00:35
いや、普通に移植性の高いlock-free queueとか書けるから。

788:デフォルトの名無しさん
09/09/06 17:04:16
ハードリアルタイムやったことないやつって性能無視の安定指向が強いよな


789:デフォルトの名無しさん
09/09/06 17:07:38
マシンパワーの需要と供給の比がカツカツかトントンか余りまくりかで全然違うからな
それを無視して、どれか一つのパラダイムだけで語る奴は問題がある

790:デフォルトの名無しさん
09/09/06 17:08:37
CompareAndSetとか、既に
どの開発環境でもインラインアセンブラ関数
用意されてるから、CPU変わっても大した話
じゃないよ



791:デフォルトの名無しさん
09/09/06 17:24:48
ところでお前らlock-free queue
とか朝飯前なんだよな?

なぁどうなんだ?

792:デフォルトの名無しさん
09/09/06 17:28:54
>>789
ですよねー周りの見えない技術者ほど使えない物はないです


793:デフォルトの名無しさん
09/09/06 19:15:48
物理シミュだと、精度が要るところは安定性重視でそうでないところはピーク性能重視。
マシンパワーの配分はジョブによって違うから動的に。

794:デフォルトの名無しさん
09/09/06 21:30:11
>>791
Javaのマルチスレッド本にlock-free queueの実装が載ってたんだが。
「どうやってlock-freeを実現しているのか」は何とか理解できたが、
自分で一から書けるか、と聞かれると胸を張って「No!」と答えるしかない。

795:デフォルトの名無しさん
09/09/06 21:32:03
>>791
俺は今書いてる
書いたらここにうpして

虐めて貰おう

796:デフォルトの名無しさん
09/09/06 22:00:21
要求条件によって実装も細かく変わるからなぁ、lock-freeは

797:デフォルトの名無しさん
09/09/06 22:08:59
IntelのMathKernelLibraryはやばい
あれこそプロの仕業だ

798:デフォルトの名無しさん
09/09/06 22:28:11
>>781のような世界では
LockFree程度じゃ満足されないぞ。

RCUとかを使ってCasFreeにして、
メモリバリア(バスロック)を減らさないと充分ではないと言われるんだ。
メモリバリアがあると、シングルコアでもバスクロックで数クロックを消費するが
これが他のコアのCASが原因でも起こるわけだからな。

799:デフォルトの名無しさん
09/09/06 23:31:17
>>797
MKLは、OpenMP対応しているから勿論OpenMPで並列実行させてもいいのだけれど。
意外なことに、MKLを使ったプロセスを複数同時実行させてもリニアリティが高いのが凄い。

800:デフォルトの名無しさん
09/09/07 01:19:14
>>798
lock-freeが要求によって実装がまちまち、ってのはそういうのも含めたつもり
CASは使わないがメモリモデルや要件的にRCUも不要な場合とか、色々あるからなぁ

801:デフォルトの名無しさん
09/09/07 01:20:34
ロック中に、割込処理みたいなコンテキストスイッチしない人が飛び込んできたら
デッドロックしちゃうけど、一般的にこういうのはどうやって回避する?

802:デフォルトの名無しさん
09/09/07 01:31:35
飛び込ませないとか

803:デフォルトの名無しさん
09/09/07 01:35:48
割り込み処理の中で何かをロックするというのはやめようよ

804:デフォルトの名無しさん
09/09/07 07:16:58
>>801
longjump

805:デフォルトの名無しさん
09/09/07 09:58:24
ロックって他のスレッドをロックしなければコスト低いのな
特定のクラスの関連のない処理を同じロックオブジェクト使ってすげー遅かったのが
処理ごとに別のロックオブジェクト使うようにしたら殆どコストが無くなった

当たり前だよな・・・


806:デフォルトの名無しさん
09/09/07 11:44:54
>>805
では聞くが、それは本当にロックする必要があったのか?w

807:デフォルトの名無しさん
09/09/07 11:54:40
あるし

808:デフォルトの名無しさん
09/09/07 12:56:39
ロックの粒度は可能な限り小さくする派です
でもそれ以前になるべくロックしないでいいように設計します


809:デフォルトの名無しさん
09/09/07 15:37:35
それが言いたかったんです
けど小さいロックを連続でするくらいなら少し大きなロックを1回の方が効率いい時もある

810:デフォルトの名無しさん
09/09/07 15:47:31
以前ねえ、ロックの粒度を細かくしていったら
滅多に競合しないのに、オブジェクト毎に計数千個のロックが作られる事態になったことがある。
(rwlockのエミュレーションで、Win32でやってみたらHANDLEの使用量が跳ね上がったり)

で、こういう場合はどうするのが妥当?

1) そのまま数千個使う
2) ハッシュ等でロックを減らす
3) がんばってrease-releaseする形にする

まあ3)が一番まともかと思うんだけど
CASとかを使ってうまく解決できるのかな。

811:デフォルトの名無しさん
09/09/07 15:55:47
>>809
> 少し大きなロックを1回の方が効率いい時もある

ロジック的に必須な少し大きなロックを洗い出して、ち
まちま小さなロックを作らないように設計するかな。

大抵他のものと絡めて排他する必要が多いから、部品単
位にロックを用意することはあまり無い。

「粒度を小さくする」っていうのはその上でロック期間
が短くなるようにすることだと思ってる。

812:デフォルトの名無しさん
09/09/07 22:00:28
compare_exchange_strong
compare_exchange_weak

の違いってなんなんですか?



813:801
09/09/08 01:50:20
割り込み中に重たい処理をやりたくないから、割り込みじゃない人に
重い処理をやらせようと思って、タスクキューみたいなのをこしらえて
せっかくだから処理を全部タスクキューにやらせようと思ったのよ
そしたらキューにタスクを積む処理で詰んだ

814:デフォルトの名無しさん
09/09/08 02:16:44
頑張って、「キューに追加/取り出しの処理」をlock-freeにするんだ。
場合によってはキューのデータ構造から書き直して、な。

815:デフォルトの名無しさん
09/09/08 07:56:26
単純にタスクキュー触る間だけ割り込み禁止に・・・

処理させたいタスクに対応するビットフラグ立てるだけでもよくない?

816:デフォルトの名無しさん
09/09/08 09:53:40
割り込みで lock-free キューに詰んで、表側で適当な
ディスパッチタイミングで必要な処理を起こす、ってい
うのなら出来そう。キューの保持数が 0 → 1 のタイミ
ングで通知を送って…とかだと詰みそう。

817:デフォルトの名無しさん
09/09/08 10:22:40
lock-free のほうが簡単では?
たとえば、A B Cの処理は衝突無し、順序関係無しだったら
3つのスレッドのキューに渡すだけでしょ?
なんで、マルチスレッドは、排他制御や、待ちの方が発展したのか不明。こっちの方が難しいだろ。

818:デフォルトの名無しさん
09/09/08 10:37:33
lock-freeって、実際にどういうアトミック命令を組み合わせて実装すんだ
それっぽい紹介サイトがみつからねぇ・・・

819:デフォルトの名無しさん
09/09/08 10:57:57
アトミック命令はアルゴリズム次第で不要だろ。
このようにしたら、メモリの共有部分は出ないから、失敗は出ない。
すべてこのような分割にしたらいい。

> 預金残高の書き換え処理をn並列で行いたいなら、n個Wait-freeキューを作り、
> 口座番号をnで割った余りでどのキューに入れるか決めるという方法で対応できる。

Lock-freeとWait-freeアルゴリズム - Wikipedia
URLリンク(ja.wikipedia.org)



820:デフォルトの名無しさん
09/09/08 11:08:36
コンペア・アンド・スワップを使わないと
処理がうまくいかないケースを知りたい。


821:デフォルトの名無しさん
09/09/08 11:16:06
なにこれむずい

822:デフォルトの名無しさん
09/09/08 11:48:12
>>815
割禁は嫌だしビットは複数積めないよね

823:デフォルトの名無しさん
09/09/08 14:47:46
>>820
俺は逆にCAS無しで上手くいくケースを教えて欲しい

824:デフォルトの名無しさん
09/09/08 15:57:19
>>822
以下の方法なら、これなら(フラグの)ビットは1個あれば済むよ。
実際にUNIXのデバイスドライバ(STREAMS)で実装した。

タスクキューを複数のサービススレッドが共有する。
割り込み処理ではタスクキューにイベントを入れてフラグを立てる。
複数のサービススレッドが一斉に起きて、最初にスケジュールされた
スレッドだけがイベント取り出しに成功しフラグを落とす。
他のスレッドはタスクキュー空(から)なので、再び待ち状態に入る。
割禁の範囲はタスクキューとフラグを触る時だけ。

UNIXでハードなリアルタイム性は要求されないから、可能な手法だけどね。

825:デフォルトの名無しさん
09/09/08 16:08:34
Mac OS X 10.6(Snow Leopard)の話題だけど、
こんなのはWindowsやUNIX/Linuxでは常識なのかな?

マルチコア時代の新機軸! Snow LeopardのGCD(Grand Central Dispatch)
URLリンク(ascii.jp)

826:デフォルトの名無しさん
09/09/08 16:12:39
ぜんぜん常識じゃないよ。
Mac OS はいい意味で、ようやっとるなと思う。

827:デフォルトの名無しさん
09/09/08 17:14:56
まだ途中までしか読んでないが

完全自動じゃないけど
IOCPでの、CPU数にあわせた同時実行数自動決定が、似たような仕組みなんじゃないか。
プールするスレッド数は(一般にCPU*2とか言われているが)自由なんだし。

ただ、ライブラリやフレームワークがそれを利用するように作られているか、といえば
答えは明らかにノーだけどね。

当然、言語仕様なんか触ってないから、
一つ一つのジョブは自分で切り分ける必要があるし、
手間は段違いだろうね。

828:デフォルトの名無しさん
09/09/08 17:36:21
>>826
しかし、依存性のないブロックに分割するのは手作業なので、
その記事で絶賛されているほど楽になった感じはしないけどな。
結局自分でワーカースレッドを起こさなくてもいいってだけなので
windowsでいうと、ファイバを利用したスケジューリング用のライブラリがあって
それを利用してコードを書いてるような感じだ。


829:デフォルトの名無しさん
09/09/08 17:51:51
斜め読みだけどOpenMPの発展系といった感じかな?
MSだとParallel LINQに近い気がする。

830:デフォルトの名無しさん
09/09/08 17:58:20
>>823
819の預金処理は、同時にメモリにアクセスすることは無いだろうが。
口座番号 % n ごとに処理する。 それぞれのスレッドは独立していて
各スレッドが順次処理している限り、衝突など無い。

831:デフォルトの名無しさん
09/09/08 18:17:30
>>828
依存性を判断してブロックに分割すれば、あとはフレームワークまかせなのだから、
設計者にとっては、かなり負担を減らせるのでは。Apple絶賛はさておき。

判断そのものの自動化は、副作用が前提な手続き型言語では非常に困難だから、
データフロー型言語が一般化する時代にならなければ実現しないと思われ。
今の流行ならHaskellやF#みたいな関数型言語が近い位置にいる。

あと、GUIライブラリとの連動が考慮されている点も設計者にとっては大きいね。
画像編集や3DCGみたいな分野で、Macの勢力が一気に増大する要因になるかも。

832:デフォルトの名無しさん
09/09/08 18:42:19
>>824
割禁が使えないときはどうするよ

833:824
09/09/08 19:15:59
>>832
(>>824の話は)割禁が使えるUNIXデバドラでの実装だから、
割禁が使えないときのことは分からない。

というか、割禁がまったく使用禁止な世界(ドライバ開発?)というのが想像つかないんだけど。
サービススレッドは定期的に(Lock-Freeな)キューをのぞきにいくのかな。
それほどレスポンス性能にシビアな世界で、ポーリング方式を採用するのは逆効果な気がする。

Lock-free/Wait-freeには全く詳しくないんだが、割禁が使えない世界というのを、
もしよければ教えてくれないか?

834:デフォルトの名無しさん
09/09/08 20:03:26
>>819
>> 預金残高の書き換え処理をn並列で行いたいなら、n個Wait-freeキューを作り、

「Wait-freeキューを作り」の中で、アトミック命令が使われているんだが
そういう意味では無いのかな。
単に「自前で実装する必要があるか否か」という意味なら
いくらでも「○○は不要」なものがあるだろう。

>>833
「割り込み処理」というのはハード的にはまあ確かに割り込みだが
処理内容的には、「別スレッドからの非同期な処理要求を処理するか」に近い。
つまり、割り込み禁止とは「排他ロックを獲得してから処理を開始する」
ということと同様になる。
実際、あまりに長時間割り込みを禁止していると割り込み要求が破棄されるものがあったと思うが
これは、別スレッドからのtrylock要求が規定に達したのであきらめる、というのと同じかと思う。

だから何ってほどでもないけどね。
実際には、「割り込み処理の入り口でロックを獲得」という
(やってはいけない)やり方をせずに済むわけだから。
ただし、通常は競合が無い限りCAS2回で済むロックの獲得/解放の変わりに
システムコールにつながるであろう割り込み禁止処理を入れるというのは
普通のユーザーアプリケーションにとっては
コストが大きすぎて採用できないだろうけどね。
(x86のcli/stiも特権命令だしね)

835:デフォルトの名無しさん
09/09/08 20:12:24
>>834
Wait-free関連のどんなライブラリも不要だろ。
このケースだとスレッドをn個つくって、
各スレッドは、渡された処理を順にこなすだけ。
どこにも衝突するところは無い。
( 同銀行間での送金処理があればぶつかるが。)

836:デフォルトの名無しさん
09/09/08 20:20:46
要するに、メモリ共有のある部分を並列処理しなければ、何の問題も出ないって事だな。
メモリ共有しながら並列処理しなければ、出来ない(パフォーマンスが落ちる)
ケースってどんなのがあるの?
アルゴリズムの工夫で解消無理なの?

837:デフォルトの名無しさん
09/09/08 20:20:56
>>835
そのスレッドに処理を渡す時点で、CASが必要だと思うが。

838:デフォルトの名無しさん
09/09/08 20:24:45
>>837
そうか。
処理を渡す側が、マルチスレッドの場合があるか。 ATMは日本全国にあるからね。


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch