同じ処理をスレッド化により高速化させようと考えています。が、スレッド化で遅くなってしまいました。スレッド内での処理時間が短いとスレッド化のメリットがないのでしょうか?
ためしに1つだけ実行する処理をスレッドにして処理させた場合とメインスレッドで処理させた場合との時間を計ったところスレッド化の方が2倍以上
遅くなりました。
処理がおかしいのでしょうか?スレッドはそのようなものでしょうか?
=====
TMeasThread = class(TThread)
private
Fa : Integer;
Fb : Integer;
protected
procedure Execute; override;
public
// constructor & destructor
constructor Create(a, b: Integer);
destructor Destroy; override;
end;
TTestControl = class
FMeasThread : TMeasThread;
procedure TestStart(a, b: Integer);
end;
// TMeasThread
constructor TMeasThread.Create(a, b: Integer);
begin
inherited Create(True);
FreeOnTerminate := True;
Fa := a;
Fb := b;
Resume;
end;
// Execute
procedure TMeasThread.Execute;
begin
TestExecute(Fa, Fb);
end;
// 測定開始
procedure TTestControl.TestStart(a, b: Integer);
begin
it スレッドにより実行 then
begin
FMeasThread := TMeasThread.Create(a, b);
FMeasThread.OnTerminate := OnTerminate;
end
else
begin
TestExecute(a, b); // スレッドで実行するものと同じ処理をメインスレッドで実行
end;
// 以下の動機処理は等は割愛します
end;
procedure TTestControl.OnTerminate(Sender: TObject);
begin
FMeasThread := nil;
end;
procedure TestExecute(a, b: Integer);
begin
// 何もしない
end;
マルチスレッド化は処理を高速化する手法ではありません。
複数の処理を細切れにしてあたかも同時に実行しているように見せるための処理です。
ただ、DelphiのヘルプのTThreadの説明にもあるとおり特定の処理に関しては望むパフォーマンスを得られる場合があります。
ただ、ナカシンさんはどのような処理をしたいかを明記していないため、その処理をマルチスレッド化すべきかどうかの判断がこちらではできません。
ちなみに例に挙げた「何もしない処理」をマルチスレッド化してもスレッドの作成・破棄等余分な処理が加わるため、処理の応答時間が遅くなるのはあたりまえです。
りっきぃさん。はじめまして。回答ありがとうございます。
私のやりたいことは、単純に同じ処理を並列で処理させたいのです。たとえば、この場合テスタを使用して測定を行なうのですが、今までメインスレッドで1台のテスタで1回測定していたものをマルチスレッドで複数のテスタで複数回同じ測定を行なうことが目的です。
単純に10台のテスタを直列に処理していたものがスレッドによりだいたい10分に1になればと考えています。(10分に1にならないことは分かっています)
>スレッドの作成・破棄等余分な処理が加わるため
分かっているつもりですが、余りにも遅くなったので何かあるのかと質問いたしました。因みにpriorityをtpTimeCriticalにすると始めは速くなるのですが、そのうちだんだん遅くなります。
1.複数のテスタがそれぞれ独立したIOポート(COM1〜10のような)であるか?
これがもしポートが共通でテスタをスイッチングしているようでしたら結局この部分がシーケンシャルな処理を行っているので並列処理のメリットは生じません。
2.テスタからデータを読み込むだけでなくほかの処理(読み込んだデータを出力するなど)を行っていないか?Synchronizeを使用して同一のコンポーネントに出力するなど行っているとこの部分がシーケンシャルな処理になるので(以下略
3.スレッドの寿命が短すぎないか?
OSやCPUによって値は異なりますが、スレッドの寿命や要求している処理が10〜20msのオーダーですと実際はタイムスライスが発生せず結果的にシーケンシャルな処理に(以下略
思いつく事を書いてみました。
処理の多重化のポイントはどの部分がボトルネックになっているかです。
この辺はハードのスペックに依存する部分が多いのでトライ&エラーでしか検証できないのですが、1〜3の条件をクリアしてても問題があるとするともしかすると多重度が高すぎるのかもしれません。
「スレッド内での処理時間が短いとスレッド化のメリットがないのでしょうか?」
「priorityをtpTimeCriticalにすると始めは速くなるのですが、そのうちだんだん遅くなります。」
このへんのキーワードから察するにスレッドスケジュールがキツ過ぎるのかもしれません。10台のテスタを2〜5台ずつにするなどして多重度を下げてあげるとうまくいきそうな気がします。
長々と書きましたが参考になれば幸いです。
りっきぃさん。毎度毎度回答ありがとう御座います。
恥ずかしいのですが、原因がわかりました。現象はDelphiからのデバッグ環境で実行するとこのような現象が発生することがわかりました。りっきぃさんには、大変ご親切な回答をいただき誠にありがたく、大変恐縮しております。
ただ、上記のご質問(ご回答)の件は大変参考になりました。
実際、IOポートはひとつなので同期処理など行なわなくてはならなくなり、一部シーケンシャルにしなければならなくなります。
重ね重ねありがとう御座います。
また、よろしくおねがいいたします。
ツイート | ![]() |