• ベストアンサー

マルチスレッドプログラミングについて

現在DirectXでマルチスレッドを使ってプログラムを組んでいますが、その処理の中で描画のみを切り離してスレッド化しようと思っています。 そこで質問ですが、描画スレッドに渡す処理の個数が多い場合は描画スレッドを2つにして処理する個数も分けたほうが処理は早くなるのでしょうか?

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

  • ベストアンサー
回答No.1

 結論から言えば描画デバイスの数と描画スレッドの数は1対1・・・ つまり、描画先が1つなら1つのスレッドで描画した方がいいでしょう。  そうしないと描画順の制御もしにくいですし、片方が1プリミティブを描画中、 もう片方のスレッドは待たない(DirectXが内部でウエイトをかけているはず)と いけないわけで、効率も落ちるかと。

GCShuji
質問者

補足

ご回答ありがとうございます。 なるほど、描画デバイスに対して描画スレッドは1対1でしたか・・・ そちらのほうが確かに制御がしやすいですね。ありがとうございました。

関連するQ&A

  • マルチスレッドプログラミングの利点について

    はじめまして。 質問があります。 現在マルチスレッドプログラミングについて学習しているのですが、 学習を進めていくうちにある疑問が思いつきました。それは、 マルチスレッドで実装した方がよい場合とシングルスレッドで実装 した方がよい場合の区別がよくわからないということです。マルチスレ ッドで実装する利点は、例えば、応答性を向上させるとか、 入出力操作が関わっているときにCPUの空き時間を利用して別スレッド で処理を行わせることによってスループットを向上させることぐらいしか思いつきません。また、CPUが1個しかない環境では、 CPUをフル活動するようなプログラムでは、下手にマルチスレッドで 実装するよりもシングルスレッドで実装したほうが排他制御しない 分だけ処理スピードは上であると思っているのですが、間違いでしょうか?マルチスレッドで実装した場合の利点は上述したこと以外にも 何かあるのでしょうか?ご教授お願いします。

    • ベストアンサー
    • Java
  • プログラムのマルチスレッド化について。

    マルチスレッド化したプログラムの作成を行いたいと思い、 前に作った、スライス画像を作成するプログラムを マルチスレッド化しようと、自分作ってみたのですが、デバック中に エラーで、止まってしまいます。 プログラムはこれです。http://koushi12.if.land.to/main.h この中の、///ここでエラーがでます/// というところで止まってしまいます。 ちょっと長いので、もしお時間ある方いらっしゃっいましたら見ていただき、修正箇所を指摘していただきたいのですが、 プログラム読むほど時間無い方には、質問で答えて頂きたいのですが、 各スレッドに、データ(引数)を渡すところで、 1つのデータ(例えばポインタで作ってある、画像データ)を、2つのスレッドに渡しても大丈夫なのでしょうか? データは、2つ作って、それぞれを、それぞれのスレッドに渡さないとダメなのでしょうか? それと、例えば、出力関数などを1つだけ作ってあったとして、 それを、各スレッドの中で、呼び出して大丈夫でしょうか? 関数も、各スレッドが呼び出しで衝突しないように、2つ作る必要があるのでしょうか? すみませんが、回答よろしくお願いします。

  • マルチスレッド化。

    今とても大きな配列を使用し、長時間処理をするプログラムを組んでいます。元々処理時間に1時間を要するプログラムを2分で処理を完了するまでに仕上げました。 しかし、探究心はおさまらずもう少し高速化に挑みたいと考えています。 過去に「猫でもわかる」のSDK第1章と2章を学び、マルチスレッドのプログラムをSDKで組んだことがあります。それを利用してマルチスレッド化を実現したいと考えています。 言語はCでVisualStudio2005を使用しています。 *疑問1   SDKの場合WinMain関数とプロシージャからの実行で_beginthread関数を記述すれば処理が開始されます。 Cでもmain関数内に記述すれば、SDKと同様に処理できるのでしょうか? *疑問2 _beginthread関数の引数に関してです。 第1引数にvoid型のスレッド関数、第2引数に0?、そして第3引数にはスレッド関数に渡すデータの引数を記述すると把握しているのですが、渡したいデータは複数あり、***型と**型、それに変数を数個とスレッド関数に渡したいデータだらけなのですが、どのように記述すればよいでしょう? *疑問3 2つのスレッドを作成しようと考えていますが、その2つのスレッドで1つの大きな配列を共有して処理したいと考えています。 そのため、スレッド間の同期が必要になるわけですが同期の種類にもクリティカルセクションやミューテックス、イベントと豊富でどれを使用すれば良いのか迷ってしまいます。厳密に同期を取り処理をするにはイベントが一番良いと考えています。 これらの疑問に答えられる方はアドバイスをよろしくお願いします。

  • 非同期プログラミングは必ずマルチスレッド?

    非同期プログラミングは必ずマルチスレッドプログラミングになりますか? ここでいう非同期プログラミングとは、 何かのメソッドを実行してその処理(処理Aとする)の結果を待たずに次の処理Bを実行できて、処理Aが終わったらコールバックやデリゲートで、あらかじめ決められたメソッド(finishとする)が呼ばれるといったものです。 処理Aを実行するメソッドを呼ぶ ↓ すぐに処理Bを実行開始(このときバックグラウンドで処理Aが走っている) ↓ 処理Aが終了したのでfinishメソッドが実行される 例えば、Objective-CのNSURLConnectionで非同期通信するときのようなやつです。 こういった非同期プログラミングは、必ずマルチスレッドを使うことになりますか? 普通、別スレッドで処理させるときはスレッド用のライブラリを使うなどして明示的にマルチスレッドプログラミングをしますが、上のように非同期のメソッドを使うと、その裏で自動的に別のスレッドが動くのでしょうか。 それとも、単一スレッドのみで、非同期プログラミングできるでしょうか。 なお、特殊な言語やOSによっては、いくらでも可能性があると思いますので、 メジャーな環境(Windowsや、スマホ) のみに限定してお願いします。言語で言うと、C、C++、Objective-C、Javaあたり。 また、上の「処理A」が終わったとき、メソッド「finish」が呼ばれるとすると、 処理Bの実行中にどのようなタイミングでfinishが呼ばれるのでしょうか。 処理Bはどのような形でfinishに切り替わるのでしょうか。いきなりfinishに処理を奪い取られるのでしょうか

  • マルチスレッドプログラミングについて

    マルチスレッドプログラミングについていくつか教えて下さい。 マルチスレッドの基礎がまだ分かってないので初心者でも分かり易いようにお願いします。 1:イベントオブジェクトについて教えて下さい。 「イベントオブジェクト」の概念がよく分かりません。 ○シグナル状態と非シグナル状態とはどういう状態なのでしょうか? ○自動リセットの場合ではどのタイミングで切り替わっているのでしょうか?(下記のソースの場合) ○手動リセットの場合ではどのタイミングで切り替えればよいのでしょうか?(下記のソースの場合) 2:CloseHandle() と ExitThread() について教えて下さい。 ○この2つの関数の役割の違いについて教えて下さい。 「スレッドハンドルを閉じる=スレッドを終了」ではないのでしょうか? また、これらの関数実行時にシグナル状態は気にする必要はありますか?(シグナル状態にしなくてよいのか?) 下記のソースは簡略化のためかなり省略されています。 DWORD WINAPI ThreadProc( DWORD i ) { while( true ) { DWORD r = WaitForMultipleObjects( 2, hEvent, FALSE, INFINITE ); if( r == WAIT_OBJECT_0 ) { // 処理1 } else if( r == WAIT_OBJECT_0 ) { // 処理2 } else { ExitThread( TRUE ); // スレッド終了 } } } void MainProc() { // 自動リセットのイベントオブジェクト作成 for( int i=0; i<2; i++ ) { hEvent[i] = CreateEvent( NULL, FALSE, FALSE, NULL ); } // スレッドを作成 hThread = CreateThread( NULL, 0, ThreadProc, NULL, 0, &dwThreadID ); }

  • マルチスレッドについて

    現在”猫でもできる”の87、88章を学んでおります。 まず87章でマルチスレッドの根本的なやり方を学びましたが、いきなり疑問が浮かびました。 _beginthread関数によりスレッドをスタートさせ、この関数で登録した関数内で_endthread関数を実行し終了させていることは分かります。 しかし_beginthread関数で登録した関数に引数を渡す処理がどの部分で行われているのかわかりません。 登録する関数はvoid型で引数はvoid*型でなければいけないことは分かったのですが、プログラムのどこを見てもこの登録した関数に引数を渡す処理が行われていません。 その辺の動作の説明を分かる方でいいのでよろしくお願いします。 そして88章では排他制御のマルチスレッドを行うプログラムの製作を行っているのですが、ちょっとした疑問が浮かびました。 EnterCriticalSection関数、LeaveCriticalSection関数ではさまれたプログラムは排他制御され他からアクセスされない。 この関数はこんな理解で良いんですかね? この理解で行くと、88章で説明していきますが、子ウィンドウを2つ作成しそれぞれのプロシージャ内で排他制御された関数をスレッドとしてスタートしています。 この2つのスレッドの動作についてですが、互いに排他制御関数が記述されているため、動作としてはまず左の子ウィンドウのスレッドが処理されている場合、右の子ウィンドウのスレッドは停止している。そして左の子ウィンドウのスレッドの排他制御が解放されたときに、右の子ウィンドウのスレッドが開始する。 そしてあるとき左の子ウィンドウのクライアントウィンドウ内で右クリックされた場合、その時点で排他制御されたスレッドが終了するのを待ち、終了したらcountを+1する。 こんな動作が行なわれていると理解してよいのでしょうか?

  • マルチスレッドでのDirectXの使用について質問なのですが

    マルチスレッドでのDirectXの使用について質問なのですが 現在_tWinMain内でゲーム用スレッドを登録して スレッド内でDirectXの初期化と解放を行っています それでプログラム終了の際に Direct3D9: (ERROR) :Final Release for a device can only be called from the thread that the device was created from. と出て悩んでいます。 googleで調べてもそれらしいところが見当たらないので困ってます・・・ 解決方法があればぜひよろしくお願いします。

  • マルチスレッドについて。

    今、大きな配列を元に処理を行うプログラムを作成しています。 シングルスレッドでも十分速度を向上するようチューニングに成功しましたが、マルチスレッド化をすればさらに速度を向上させることができるだろうと考え、先日マルチスレッドかに成功しました。 しかし・・・奇妙な現象が起こりました。 マルチスレッドで性能を引き出すには、排他制御はないほうが良いと考え、メモリは食いますがスレッドに与える入力情報(大きな配列)を2つ用意し、排他制御なしの2スレッドを実行できるようにしました。しかしやはりメモリを消費しすぎてしまうため、配列にアクセスする部分のみ排他制御を行うようクリティカルセクションを設定し入力情報を2スレッドで共有して処理を行うよう組み替えました。 結果、やはり排他制御なしの場合よりはるかにスピードダウンしてしまい、シングルスレッドより少し早い処理時間で終了してしまいました。 余りにも悔しいため、ちょっと危険な実験だとは思いましたが、入力情報を2つのスレッドで共有しているにもかかわらず、排他制御の部分、つまりクリティカルセクションを取り除いて実行してみようと考えました。予想としては同時にアクセスし衝突が起きてエラーで停止してしまうと考えましたが・・・・・・ 結果なぜかエラーなく処理をし続け、普通に終了してしまいました。 これはなぜでしょう? 偶然にも共有情報に同時にアクセスすることがなかったためでしょうか?

  • マルチスレッドプログラミングの参考書

    スレッドやプロセスなどの意味は理解しているつもりです。 実際プログラミングをする技術を身につけたいと思っていますが おすすめの、勉強(参考)となる書籍はありますでしょうか? プラットフォームはLinux系です。 pthreadやselectを使用できればよいです。 最終的にどんなことがしたいかといいますと マルチスレッド対応したソケットプログラムを 作ってみたいのです。 シングルスレッドであれば、ある程度作れるのですが マルチスレッドではどのように作成していいのか・・・ 参考になりそうなHPでもいいのでよろしくお願いします。

  • DirectX LPDIRECT3DDEVICE9のマルチスレッドでの使用について

    お世話になっております。 さて、現在DirectX 9.0cを用いたゲームを製作しています。 このゲーム内で、いわゆるNowLoadingの画面を作成しているのですが、ここで気になることがあります。 ここでのNowLoadingの要件は、"描画とは別にスレッドを作成し、そのスレッドでロード処理を行う"ことです。 そこで、ドキュメント(古いDirectXの日本語ドキュメント)でマルチスレッドについて言及している箇所を検索してみると、CreateDeviceの引数にD3DCREATE_MULTITHREADEDを入れると、マルチスレッドに対応すると書いてあります。しかし、同時にパフォーマンスを下げるとの記述もあります。 しかし、D3DXCreateTextureFromFileなどD3DXCreate**系の関数が、LPDIRECT3DDEVICE9に対して参照だけを行い、BeginSceneなど描画に関する関数の挙動には(LPDIRECT3DDEVICE9に同時にアクセスしたとしても)、なんら影響がないならば、わざわざこのD3DCREATE_MULTITHREADEDフラグを使いたくありません。 そこで、サンプルを作成してみました。 http://briefcase.yahoo.co.jp/bc/multithreaddevicesrc/lst?&.dir=/&.src=bc&.view=l このサンプルは、上記の処理をD3DCREATE_MULTITHREADEDフラグをいれず、そのまま行っているもので、テクスチャを別スレッドで、ひたすらロードと、解放を行っています。これを実行した結果、特に問題ない(強制終了などしない)ように見えました。 この結果は、"たまたま動いている"だけなのでしょうか、それとも"必然的"なもので、別段行ってもいいものなのでしょうか?もしくは、状況による(SetRenderStateなどの使い方による、など)ものなのでしょうか? ご教授よろしくお願いします。 環境は、DirectX9.0c (2008March)、XP sp3 になります。

専門家に質問してみよう