DOBON.NET DOBON.NETプログラミング掲示板過去ログ

マルチコア上でのWaitForSingleObjectのパフォーマンスについて

環境/言語:[VisualStudio2003 Professional Edition]
分類:[その他]


はじめまして。まるちと申します。

マルチコア(CoreDuo)上でのWaitForSingleObjectについて質問があります。
疑問は、マルチコアでプロセス間同期をした場合、CPUのパワーを使い切っていない?ということです。

現在、2つのプロセスを同期させて動作するアプリを開発しています。
プロセス間同期にはSetEvent、WaitForSingleObjectを使用しています。
プロセス間の同期はかなり頻繁に行われるので、同期部分のみを抽出し、
パフォーマンスを測定しました。

ソースコードは以下のようになります。
■exe1.cpp
void wait() {
  HANDLE event_1 = CreateEvent(NULL, FALSE, FALSE, "event_1");
  HANDLE event_2 = CreateEvent(NULL, FALSE, FALSE, "event_2");
  for (int i = 0; i < 10000000; i++) {
    WaitForSingleObject(event_1, INFINITE);
    SetEvent(event_2);
  }
}
■exe2.exe
  HANDLE event_1 = CreateEvent(NULL, FALSE, FALSE, "event_1");
  HANDLE event_2 = CreateEvent(NULL, FALSE, FALSE, "event_2");
  for (int i = 0; i < 10000000; i++) {
    SetEvent(event_1);
    WaitForSingleObject(event_2, INFINITE);
  }
}

シングルプロセッサ(Pentium4 2.8GHz)で実行させたところ、
10,000,000(1000万)回の同期に掛かる時間は44316ms(44秒)でした。
このとき、CPU負荷は100%(カーネル時間が80%程度)でした。
これはまぁ問題ないように思います。

マルチプロセッサ(CoreDuo 1.66GHz)で実行させたところ、
10,000,000(1000万)回の同期に掛かる時間は17141ms(17141秒)でした。

分からないのは、マルチコアの場合のCPU負荷が100%にならないことです。
上記のテストではCPU負荷は10%程度(CPU0、1共5%程度、ほぼカーネル時間)でした。
残りの90%程度はアイドルとなっていました。

なぜ、マルチコアの場合にはCPU負荷100%にならないのでしょうか?
CPUパワーをフルに使いきっていない理由がわかりません。
理由をご存知の方はご教示いただけたら幸いです。

また、どうにかしてCPU負荷100%にして高速化できるのであれば
その方法もお教えいただきたいと思います。


なお、上記のテストではCPUアフィニティは設定していません。
両プロセスを同じCPUに割り当てた場合はシングルプロセッサ同様
CPU負荷100%になることは確認しました。
> なぜ、マルチコアの場合にはCPU負荷100%にならないのでしょうか?
> CPUパワーをフルに使いきっていない理由がわかりません。
> 理由をご存知の方はご教示いただけたら幸いです。

  ???
  何故、CPU負荷を使い切らないといけないのですか?
  本来、CPU負荷を100%食ってしまう方がダメなはずなんですが。

> また、どうにかしてCPU負荷100%にして高速化できるのであれば
> その方法もお教えいただきたいと思います。

  マルチコアでもっと高速化したいということですか?
  それともシングルCPUで高速化したいということですか?

  それと今回のプロセス間同期をもっと高速化したいと言うことで
  あれば、確かWaitForSingleObjectが一番効率よく同期を取る方法
  だった(何か読んだ)ので、それ以上の高効率なものは無かった
  ように思います。よって、できない・・・と思います。

  尚、そのプロセスの優先順位を上げたりと、若干の高速化の方法は
  あるとは思いますが。

> なお、上記のテストではCPUアフィニティは設定していません。
> 両プロセスを同じCPUに割り当てた場合はシングルプロセッサ同様
> CPU負荷100%になることは確認しました。

  高速化とCPU負荷率は、分けてお考え頂くのがよろしいかと・・・

以上。
まるちです。

ご回答ありがとうございます。

>   ???
>   何故、CPU負荷を使い切らないといけないのですか?
>   本来、CPU負荷を100%食ってしまう方がダメなはずなんですが。
説明不足でした。
このアプリを動作させるために専用のPCを準備するため、
CPU負荷が100%になってもよいので可能な限り速くしたい、
という希望があります。


>   マルチコアでもっと高速化したいということですか?
>   それともシングルCPUで高速化したいということですか?
マルチコアで高速化したいと考えています。


>   それと今回のプロセス間同期をもっと高速化したいと言うことで
>   あれば、確かWaitForSingleObjectが一番効率よく同期を取る方法
>   だった(何か読んだ)ので、それ以上の高効率なものは無かった
>   ように思います。よって、できない・・・と思います。
そうですか・・・。了解しました。


>   高速化とCPU負荷率は、分けてお考え頂くのがよろしいかと・・・
アイドルになっているCPU時間を有効に使えれば速くなるかも、
と思い質問させていただきました。
2006/12/30(Sat) 03:36:21 編集(投稿者)

CPU 使用率云々の件は別として、同期にかかる時間に明らかな開きがあるようですね。

マルチ CPU は同期処理には不利であると想像できますが

>シングルプロセッサ(Pentium4 2.8GHz)で実行させたところ、
>10,000,000(1000万)回の同期に掛かる時間は44316ms(44秒)でした。

>マルチプロセッサ(CoreDuo 1.66GHz)で実行させたところ、
>10,000,000(1000万)回の同期に掛かる時間は17141ms(17141秒)でした。

というのは、想像よりも大きな開きがあるように私も感じます。

どうしても気になるなら、MS の技術サポートにぶつけてみてはいかがでしょうか?

「そんなもん」と言われるかもしれませんが、何かしら情報が出てくるかもしれません。
OSにもよりますが、基本的には故意的にCPUを使い切ることはできない
ようになっています。(語弊がある表現ですが・・・)
ただし、CPUを占有するプログラムを書きたいなら、他社製品ですが、そ
のようなことを行えるものは販売されています。100万円くらいします。

ただし、書き方次第では、バスの割り込みにも影響が出てしまいますので
ブルークラッシュする場合も当然あります。

アプリケーションレベルでは、まず無理とお考え頂きたい。
ただし、ユーザーモードのコードをカーネルモードで実行させれるような
ものもありますので、どこまでリスクを負った開発を行えるかです。

システムサービスやデバイスドライバーのようにアプリレベル以上での権限
で動作させると言う方法もあります。

ですが、全てに別途開発ツールを購入して・・・と言うことになります。

実際に手法は存在しますが、コストとリスクと新たな開発環境の勉強時間を
含め、どこまで可能か・・・

WinDriver や、InTime と言ったものを検索してみて下さい。
それらの一部の機能で実現は可能です。

以上。
渋木様、オショウ様

ご回答ありがとうございます。

やはりなかなか難しいのですね・・・。承知しました。

まずは現状を受け入れたいと思います。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板