- PR -

デュアルコアCPU実装PCでのマルチスレッドの有効性について

投稿者投稿内容
ヤマハブラザーズ兄
会議室デビュー日: 2006/01/19
投稿数: 10
投稿日時: 2006-07-10 18:03
現在、デュアルコアCPU(ハイパースレッディング対応/4論理CPU)を
搭載したPC上で、

 (以下はC#.netで作ったAPで実装/ADO.NET使用)
 1.複数のCSVファイルをMDBに取り込む
 2.1.のMDBを最適化
 3.2.のMDBを圧縮
 4.1.〜3.を、MDBの個数分繰り返す

という処理を行っているのですが、

処理時間短縮の為、APに
「MDBの個数分シングルタスクで処理を行っていた」のを、
「MDB群を2つに分け、並行で(マルチで)で処理を行う」
 ※マルチスレッドは、デリゲートで実現
という変更を加えたところ、以下問題が発生しました。

どなたか有識者の方、同様の経験をされた方、アドバイスをお願い
致します。

1.処理実行時間が変更前後でほとんど変わらない

 →初めて作ったマルチスレッドAPであった為、実際どの程度処理時間が
  短縮されるかわからなかったのですが、
  最も処理に時間を要していた”CSVをMDBに格納する部分”に関しては
  逆にシングルの場合より処理に時間がかかっており、
  マルチで処理された為、差し引きゼロになっている様でした。

  シングルCPUでマルチスレッドを動作させたのであれば、
  この結果を予測しましたが、デュアルコアCPUでもこんなものなの
  でしょうか?
  それとも、何かPCの設定を変更したり、APのロジック変更で
  更に効果を見込めるのでしょうか?

  ちなみに、タスクマネージャのパフォーマンスタブを見ると、
  CPU使用率履歴が4つのWindowで表示されていますが、
  それによると主に使われているのはその内2つでした。
  更に、シングルスレッドで処理を行っていた際の使用率は
  MAXで約6割程度でしたが、マルチスレッドにしても変らなかった。

2.mdbの最適化をマルチで行うと、1/3程度の割合でエラーが発生

 →mdb最適化の際に、「InteropServices.COMException(0x80004005):
  このデータベースは、マシン’xxxx’のユーザ’Admin’が排他的に
  開いています」というExceptionが頻発します。

  念のため、MDB群を2つに分ける際、処理フォルダも別々にして
  みましたが、結果は同じでした。
  CVS→MDB格納のタイミングでは同様のエラーは発生しなかったのですが、
  どなたか回避策等ご存知ではないでしょうか?

以上です。
わちゃ
大ベテラン
会議室デビュー日: 2005/12/05
投稿数: 162
お住まい・勤務地: 東京
投稿日時: 2006-07-10 19:09
まず、マルチスレッドで、処理が早くなるのは処理速度のネックが CPU である場合です。
今回の処理は、ディスク I/O が多いため、ほとんど処理速度が向上しなかったのではないでしょうか。

処理の内容にもよりますが、CPU 使用率の高い処理では、高速化の見込まれる場合が多いです。

また、ディスク I/O が多い場合は、単一スレッドで HDD の特定の部分をアクセスするのに比べて、
マルチスレッドで多数の処理を行うと、ディスクのヘッドの動きや、ディスクキャッシュが効率的に
ならずに処理速度が低下する場合があります。


Access のランタイムは、あんまり安定していなくて、たまにバグる印象があります。
うちの納品用は一番安定感を感じている、Office 2000 の SP3 を使っています。

ただ、いきなり製品のバグを疑っていると、あまり健康的じゃないので、
ちゃんとログなどを吐いて、本当に重複しているのかどうかを調べた方がよいと思います。

もっとも、パフォーマンスが向上していないのですから、原因がどうこうというよりも、
マルチスレッドをあきらめるが今回の回避策の一つとして考えられるのではないでしょうか?
macoto
常連さん
会議室デビュー日: 2006/02/15
投稿数: 25
お住まい・勤務地: 東京都/東京都
投稿日時: 2006-07-11 10:33
引用:

ヤマハブラザーズ兄さんの書き込み (2006-07-10 18:03) より:
1.処理実行時間が変更前後でほとんど変わらない



1.に関しては以下の文書が参考になると思います。

プログラミング C# 15.5 | スレッド操作指針
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdnbprocs/htm/progCharp15-01.asp

既に指摘がありますが、ここでいうところの「不確かなメリット」に該当していると思います。
未記入
ベテラン
会議室デビュー日: 2003/06/26
投稿数: 76
投稿日時: 2006-07-11 12:41
僕も同じようなことで悩んでいるので、参加させてくださいね?

 1.に関してなのですが、マルチスレッドは同一プロセス内での並行処理ではないんですか?1つのCPUで複数のスレッドが動くのだから処理が早くならない...。
 Web(IIS)で重い処理をマルチスレッドにすると、端末へのレスポンスががた落ちするのでそうではないかな〜と。

 2.は、作業領域の問題ではないですか?同じ作業領域を同じ名称で使うから駄目とか...って憶測ですけどね。

 すみません、すべて憶測ですが...。しかも回答じゃないときた!
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2006-07-11 17:16
引用:
1.処理実行時間が変更前後でほとんど変わらない


・全体的にI/O処理の比率が高い
・MDBの最適化や圧縮といった作業では並行性を上げられない
・JETエンジンは並列処理のための最適化なんてされてなさそう

といった理由でしょうか?

引用:
2.mdbの最適化をマルチで行うと、1/3程度の割合でエラーが発生
 →mdb最適化の際に、「InteropServices.COMException(0x80004005):
  このデータベースは、マシン’xxxx’のユーザ’Admin’が排他的に
  開いています」というExceptionが頻発します。


最適化の際に、全体の排他ロックの獲得を試行し、獲得できないために
出ているエラーでしょう。この状態で並行処理できない実装であれば
マルチコアによるパフォーマンス向上はないでしょうね。

引用:
1.に関してなのですが、マルチスレッドは同一プロセス内での並行処理ではないんですか?1つのCPUで複数のスレッドが動くのだから処理が早くならない...。


CPUの割り当てにプロセスの内外は関係ないはずです。
OS次第でスケジューリングに影響するかもしれませんが。

マルチコアでのパフォーマンス向上は、マルチスレッド(プロセスでも)
での平行性を上げられる処理であるかどうかに大きく依存します。
状況によってはオーバーヘッドで相殺もしくは低下するでしょう。

DBでは多数のトランザクションを並列実行するような状況であれば
マルチコアの恩恵を受けやすいのですが、ロックの競合が頻発する
ような状況ではほとんど無意味になってしまうでしょう。

とりあえず、MDBではマルチコアは無意味に等しいのでは?
複数ユーザーからの同時利用を前提にしたDBMSを使いましょう。
ヤマハブラザーズ兄
会議室デビュー日: 2006/01/19
投稿数: 10
投稿日時: 2006-07-12 14:47
皆様、コメントありがとうございます(返事が遅れてすいません)。

わちゃさん

引用:
ただ、いきなり製品のバグを疑っていると、あまり健康的じゃないので、
ちゃんとログなどを吐いて、本当に重複しているのかどうかを調べた方がよいと思います。


→メソッドの入出口等でこまめにログは出力していますが、それを見る限り重複して
 いると思います。

引用:
もっとも、パフォーマンスが向上していないのですから、原因がどうこうというよりも、
マルチスレッドをあきらめるが今回の回避策の一つとして考えられるのではないでしょうか?


→確かにおっしゃる通り。ただ、自分がやった以外に、何か方法があるのか/または
 方法が間違っていなかったか、も疑問でしたので。
 でも、複数のコメントを頂き、マルチスレッド以外の方法を検討してみる気に
 なっています。


macotoさん

引用:
既に指摘がありますが、ここでいうところの「不確かなメリット」に該当していると思います。


→おっしゃる通りの様ですね。
 ただ、msdnで言ってる事を完全には理解できてなくて、現在再度読み返している
 ところです。


ぜうすさん

引用:
1.に関してなのですが、マルチスレッドは同一プロセス内での並行処理ではないんですか?1つのCPUで複数のスレッドが動くのだから処理が早くならない...。


→すいません、初歩的な返事を返しますが、確かに同一プロセスでの並行処理ですが、
 複数CPUだったら、それぞれスレッドを割り当ててくれるんではないのですか?
 それともデュアルコアCPUをマルチコアと同じ様に考えている事が間違いなの
 でしょうか?(確かに物理的には1CPUらしいですが)

引用:
2.は、作業領域の問題ではないですか?同じ作業領域を同じ名称で使うから駄目とか...って憶測ですけどね。


→そうかもしれません。ですが、APIのプロパティにそれらしき物はありませんでした
 ので、って事はしゅさんのおっしゃる様にmdbがマルチ対応されてないのかも
 しれません。まあ、あくまでmdbは個人用dbに過ぎないので。。。
 あと、最適化の際に、テンポラリのmdbを作って一旦そちらを最適化後、元々のmdbと
 置換するのですが、当然テンポラリmdb名もスレッド毎に変更してみたものの、
 結果は同じでした。


しゅさん

引用:
最適化の際に、全体の排他ロックの獲得を試行し、獲得できないために
出ているエラーでしょう。この状態で並行処理できない実装であれば
マルチコアによるパフォーマンス向上はないでしょうね。


→全体の排他ロックというのがよくわからないのですが、mdb個々ではなく、
 ドライバから見て1つ(全体)という事なのでしょうか?
 もう少し最適化の実装方法について調べてみたいと思います。

引用:
とりあえず、MDBではマルチコアは無意味に等しいのでは?
複数ユーザーからの同時利用を前提にしたDBMSを使いましょう。


→確かにそんな気がするのですが、既にmdbで動いているシステムで、
 その性能up対応を行っているところです。
 なので、もう少し現環境のままで何とか出来ないかさぐってみます。
 (無謀かもしれませんが、exe自体をマルチ起動するとか)


以上です。

MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2006-07-12 16:01
access は どのモデル?
シングルスレッド アパートメント (STA) モデル :
1 つのプロセス内の 1 つまたは複数のスレッドが COM を使用し、
COM オブジェクトへの呼び出しは COM によって同期されます。
http://support.microsoft.com/default.aspx?scid=%2Fisapi%2Fgomscom%2Easp%3Ftarget%3D%2Fjapan%2Fsupport%2Fkb%2Farticles%2Fjp150%2F7%2F77%2Easp&LN=JA
わちゃ
大ベテラン
会議室デビュー日: 2005/12/05
投稿数: 162
お住まい・勤務地: 東京
投稿日時: 2006-07-12 18:02
マルチスレッドにすれば、複数のコアでも使用されます。

ただ、複数のプロセスにするなど、コーディングで工夫しても、DISK ネックの処理で、かつその内部処理がほとんどの時間を占めているのですから、あまり工夫の余地があるような感じがしません。

私だったら、高速化のアプローチはあきらめます。

むしろ、どうしてもということであれば、運用系で、例えば夜に自動でバッチジョブを流すようにするとか、そういった解決ぐらいではないでしょうか?

スキルアップ/キャリアアップ(JOB@IT)