アプリ版:「スタンプのみでお礼する」機能のリリースについて

 こんにちは。
質問ですが、自分の環境はWindowsXP SP3 VisualStudio.NET2005 でのC++でのプログラミングです。
まず、スレッド作成をするために、_beginthreadexを用いているのですが、このやり方で、5,6個のスレッドを作成すると処理が逆に重くなってしまいました。
このスレッドは排他制御をしていないものです。
以下にソースの一部を載せます。

/////////////////////////
// スレッド作成
BOOL TestFunc::ThreadRegist(void)
{
UINT thID = 0;

if((hThread = (HANDLE)_beginthreadex(NULL, 0, &TestFunc::tRunLauncher, this, 0, &thID)) == 0) {
return FALSE;
}

return TRUE;
}


/////////////////////////
// スレッド
void TestFunc::ThreadRun(void)
{
ras.Sprite(ene.d, ene.m, ene.s);//処理の重い画像処理
thflag = true;
_endthreadex(0);
}

// これがクラス
class TestFunc : public CTEST01
{
bool rasf;
bool thflag;
WORD set;
EffectRaster ras;
double RX, RY;

HANDLE hThread;
static UINT WINAPI tRunLauncher(void* vp) {
reinterpret_cast<TestFunc*>(vp)->ThreadRun();
return 0;
}
void ThreadRun();
BOOL ThreadRegist();
public:
TestFunc(double x, double y, WORD type);
};

このオブジェクトを多くて5~6個作っています。
上記の場所をスレッドにしない場合、逆に処理が軽くなるんです。
スレッドが5から6個でも処理が重ければ影響が出るのでしょうか?
しかしそれでもスレッドにしない場合より重くなる理由が分からないでいます。

  詳しい方がいらっしゃいましたらどうぞよろしくお願い致します。 m( )m

A 回答 (4件)

メモリの量は足りていますか?


5つのスレッドが並列に実行されたときに必要な作業用メモリの量が実メモリの量を超えていると、仮想メモリとの間で大量のI/Oが発生して全体の速度が下がるおそれがあります。

> スレッド処理に待機時間を設ければ大丈夫ということなんでしょうか?

何だか本末転倒な話になっていませんか? 演算処理の中に無用な待機時間を入れたらその分遅くなります。

元々の演算処理の中に避けられない待機時間があった場合に、CPUのコア数以上のスレッドがあればその待機時間を有効に使える可能性があるということです。
そのような待機時間が全く存在しない演算処理であってメモリが十分にあるならばCPUのコア数だけスレッドを作るのが最善です。コア数より少なくても多くても無駄が生じます。

> 排他制御にした場合でも同じ結果になるのでしょうか?

何を聞いているのか分かりませんが排他制御は速度低下の要因にしかなりません。高速化を追求するなら、しないで済む排他制御は極力避けるように設計します。
    • good
    • 0
この回答へのお礼

とっても参考になりました。
単純な話、待機時間を設ければその分遅くなるのは当然ですよね。

排他制御をすれば遅くなってしまうんですね。
処理される順番を整えるとそれなりに負担がかかるということでしょうか。

お礼日時:2012/11/04 18:25

タスクマネージャを起動して「パフォーマンス」タブを表示し、メニューから



「表示」→「CPUの履歴」→「CPUごとに1グラフ」

を選択すると、「CPUの使用率の履歴」に複数のグラフが表示されると思います。
ここには、そのPCでOSが認識しているCPUごとの使用率が表示されており、このグラフの数があなたのPCで同時に実行可能な処理の最大数となります。
もし、このCPUの数よりも多いスレッドが動いている場合、少ない数のCPUを実行中の多数のスレッドで共有して使うことになります。

マルチスレッドによる高速化は、1つのプログラムが複数のCPUを同時に使って並列に処理することで達成できるものであるので、基本的にはPCが持つCPU数と同じ数だけ処理スレッドがあるときに最大のパフォーマンスを達成できます。
もし、それよりも多くのスレッドを実行させた場合には、それぞれのスレッドが少ない数のCPUを奪い合うことになるので、スレッド数が増えるほど遅くなります。

ちなみに、「処理が重くなる」というのは「処理完了まで時間がかかる」という意味でよいですか? そうであれば処理スレッド数を制限することになります。

一方、マウスやキー入力などの画面操作や画面表示が重くなるということであれば、処理スレッドがすべてのCPUをほぼ占有してしまって、画面の処理(プログラム起動時から存在するUIスレッドで動いている)で使用できるCPU率が極端に低くなっています。
こちらの場合も基本的にはスレッドの数を減らす必要がありますが、それ以外にも処理スレッドの実行優先度を下げることも検討した方がいいかもしれないです。(処理時間が長いのであれば余計に。)
    • good
    • 0
この回答へのお礼

処理スレッドの実行優先度を下げる方法を模索してみようと思います。

>ちなみに、「処理が重くなる」というのは「処理完了まで時間がかかる」という意味でよいですか? そうであれば処理スレッド数を制限することになります。

そうです。
そうなるとやはりスレッドは少ないほうがいいんですね。
WEBでみたんですが、テストプログラムで100個くらいスレッドを生成しているんですが、なんともなかったので疑問に思っていました。
ですが、そのスレッド処理は単純なものだったので100個くらいスレッドを生成しても負担にはならないからかもしれません。

お礼日時:2012/11/04 18:31

マルチスレッドで効果があるのは


通信、入出力など、相手や装置の
待機時間があるものになります。
この待機の間に他の処理をさせる
ことで効果が出るのです。
ドットの座標計算をするだけとかの
処理ではスレッドがアイドリングに
入る契機がないのでOSが適当に
タイムスライスを区切って実行を
制御します。結局、CPUタイムは
シリアルに実行した時と変わらず、
実行制御した分だけ余計に時間が
かかります。
    • good
    • 0
この回答へのお礼

そうしますと、スレッド処理に待機時間を設ければ大丈夫ということなんでしょうか?
排他制御にした場合でも同じ結果になるのでしょうか?
スレッドに対する経験が乏しいためなかなか想像しずらいところがあってすみません。

お礼日時:2012/11/04 09:41

CPUの論理コア数を越えてスレッドを作ると,基本的に遅くなります。


スレッドのコンテキストスイッチの処理量は0ではないためです。

また,ロックがないと言っても例えばHDDへのアクセスは実質的に一つのスレッドしかできないので,
複数のスレッドが同時にHDDへアクセスするとそれも速度低下の原因となります。
そのような「見えないロック」も考える必要があります。
    • good
    • 0
この回答へのお礼

なるほど参考になりました。
HDDへアクセスするような処理が画像処理に含まれているか調べてみようと思います。

お礼日時:2012/11/04 09:34

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!