質問者
アプリの並列処理について

質問
-
アプリの並列処理についてご教示ください
<開発>
C#(framework4.7.2)
<実行環境(仮想PC)>
OS:WindowServer2019
メモリ:16GB
「CSV読み込み⇒データ加工⇒処理」に1分30秒ほどかかるアプリがあります
※CSVファイルは600列*5000行の300万データほど
このアプリを2つ同時に起動し、並列で処理させたいと思っております
※CSVファイルはそれぞれ別のファイルですアプリ自体は同時に起動するのですが、
一方の重いメソッドが動作している間は、もう一方が動作していないような感じです
※ログを確認したところ1分30秒後にもう一方のメソッドが実行している
仮想PC上で実行しているので、メモリや仮想プロセッサ数がは増やしてみましたが、特に変わりませんでした
コーディングやビルド時のオプションなどで改善できるものなのでしょうか?
そもそもハード的に難しいのでしょうか?
すべての返信
-
以下の記事の「マルチスレッドの動作原理」のセクションの図の ③ のようにマルチ CPU・コアを使って並列処理するという話になると思います。
第1回 マルチスレッドはこんなときに使う
https://www.atmarkit.co.jp/ait/articles/0503/12/news025.html
PC のマルチコアを有効に使うプログラミングをサポートするため、.NET Framework 4.0 で導入されたタスク並列ライブラリ (TPL・・・Parallel.For とか Parallel.Invoke とか) を利用できます。
質問者さんのケースでそれが利用可能かどうかは分かりませんが、検討されてはいかがでしょう。
簡単な説明は以下の記事に書きましたので興味があれば見てください。
タスク並列ライブラリ (TPL)
http://surferonwww.info/BlogEngine/post/2020/12/27/task-parallel-library.aspx -
> このアプリを2つ同時に起動し、並列で処理させたいと思っております
ということは、別々のプロセスで同じようなことを行っているという形ですよね?だとすると、以下の部分は、プログラムではない部分に要因があって、同時に処理できない状況か、同時に実行しているつもりが、実は同時に実行していなかったかのどちらかだと思います。
> アプリ自体は同時に起動するのですが、
> 一方の重いメソッドが動作している間は、もう一方が動作していないような感じです複数のプロセスで互いが外部的な要因で連動する要素がないとすれば、同時に動かしているつもりで動いていないという可能性が大きいですが、重いメソッド部分の動きが、複数のプロセスから呼び出している場合でも同時に1つしか処理できないとなっていれば、該当箇所で待機してしまうことになります。
提示されてる情報ではこの辺りの状況はわかりません。佐祐理さんも書いていますが、まずは時間がかかっている部分の特定をするところから始めるとよいと思いますよ。
とっちゃん@わんくま同盟, Visual Studio and Development Technologies http://blogs.wankuma.com/tocchann/default.aspx
-
> CSVデータをDatatableへ展開する処理が重かったので、単純にforeachをParallel.ForEachに置き換えてみましたが、
Parallel.ForEach は複数の「スレッド」で並列させるものなので、「プロセス」という言葉は合っていませんね。
また、「起動」というと「exe をもう 1 つ起動する」というイメージを抱かせるのでミスリードだと思います。単一の要素(インスタンス)に対して複数スレッドからアクセスして問題ないかどうかは、そのクラスの作りによります。
DataTable は怪しいと思います。「この型は、マルチスレッドの読み取り操作に対して安全です。 書き込み操作はすべて同期する必要があります。」
https://docs.microsoft.com/ja-jp/dotnet/api/system.data.datatable?view=netframework-4.7.2#thread-safety上記のような表現があるので、並列で処理するのには向いていないでしょう。
(読み取りは「安全」というのは、排他しているかもしれないので…。中身未調査) -
ファイルの読み込みはハードウエアを操作することになりますので、メモリー←→CPU間のデーターのやり取りよりも処理に時間が掛かります。
CSVファイルを複数に分散しても、外部記憶装置(HDD?SSD?)が一つしかなければ、同時に読み込むとハードウエアがシーケンシャルに動作しないので逆に遅くなるでしょう。
この処理時間は外部記憶装置の読み込み速度に依存したものになりますから、CPUをマルチスレッドにしても解決できないと思います。
フォルダーを監視して、読み込む元のCSVファイルが生成されたら、すぐにバイナリー形式(読み込みを少しでも早くするため)に変換するという方法ではダメですか?
-
> CSVデータをDatatableへ展開する処理が重かったので、単純にforeachをParallel.ForEachに置き換えてみましたが、CPUの負荷が上がっただけで処理時間が今まで以上に掛ってしまいました
最初の質問にあった、
> 「CSV読み込み⇒データ加工⇒処理」に1分30秒ほどかかるアプリがあります
の中身を並列化してみたということですか?
私のレスの意図は、質問に、
> このアプリを2つ同時に起動し、並列で処理させたいと思っております
と書いてあったので、「CSV読み込み⇒データ加工⇒処理」の部分を切り分けて、それを 2 つ、同じ 1 つのアプリの中で TPL を使って並列化してみてはいかがということだったのですが・・・
> 並列処理以前にもう少し根本的な部分を見直してみます
見直す余地があれば、そちらが先かもしれません。共有リソースを待機するなどがあって、TPL を使っても改善できないということがあるかもしれませんね。
でも、TPL が使えないか否か、改善できるかどうかも並行して検討してはいかがですか。TPL で改善できないとすると、どこを改善すべきかの見当がついて、やったことは時間の無駄にはならないかも。- 編集済み SurferOnWww 2021年2月23日 0:33 訂正
-
onionswordさん、こんにちは。フォーラムオペレーターのKumoです。
MSDNフォーラムにご投稿くださいましてありがとうございます。
並列で二つのプロセスを実行したい場合は、Taskで試してみてはいかがでしょうか。
次のリンクのコードサンプルをご参照のほどお願いします。
Run two dotnet processes in parallel C# with Console app .NET Core(英語となりますが)
どうぞよろしくお願いいたします。MSDN/ TechNet Community Support Kumo ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~
-
ふと、各プロセスの処理が並列になっていないというような感じだったので、ちょっと実験的にバッチファイルで、GUIアプリを2個連続で起動するように書いてみました。
具体的な内容は、以下のごく単純なバッチファイルです。
notepad notepad
すると、一つ目のメモ帳の終了を待機してしまい、二つ目が連続的には起動しないことがわかりました。
もしかして、複数同時実行が上記のような単純な実行になっていませんか?
その場合、start notepad など、スタートコマンドを経由して待機しないようにしないと同時実行されません。
時間のかかる処理の検証とは別にこちらも確認しておくことをお勧めします。
とっちゃん@わんくま同盟, Visual Studio and Development Technologies http://blogs.wankuma.com/tocchann/default.aspx