質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CPU

CPUは、コンピュータの中心となる処理装置(プロセッサ)で中央処理装置とも呼ばれています。プログラム演算や数値計算、その他の演算ユニットをコントロール。スマホやPCによって内蔵されているCPUは異なりますが、処理性能が早いほど良いとされています。

並列処理

複数の計算が同時に実行される手法

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2155閲覧

multiprocessingを使っているのにマルチスレッドのようにmainプロセスに遅延が発生する

aiai8976

総合スコア112

CPU

CPUは、コンピュータの中心となる処理装置(プロセッサ)で中央処理装置とも呼ばれています。プログラム演算や数値計算、その他の演算ユニットをコントロール。スマホやPCによって内蔵されているCPUは異なりますが、処理性能が早いほど良いとされています。

並列処理

複数の計算が同時に実行される手法

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2021/06/08 01:34

編集2021/06/08 09:00

前提・実現したいこと

pythonのmultiprocessingを使って並列処理をしたいのですが、
下のようなコードだと、マルチスレッドのようにmainプロセスに遅延が発生してしまいます。
具体的には、
mainで

print(f'1周の所要時間:{elapsed_time}\n')

を実行しているのですが、サブプロセスが1この時とサブプロセスが2こ3この時で平均的な所要時間が多くなってしまいます。
使えるCPUの範囲でサブプロセスをある程度増やしても完全な並列処理ができるようにするにはどのようにすればいいのでしょうか。
わかる方がいましたらコメントお願いします。

発生している問題・エラーメッセージ

multiprocessingを使っているのに、マルチスレッドのようにmainプロセスに遅延が発生する。
一般的なマルチプロセスだとサブプロセスの数にかかわらず、mainの一周の所要時間はほとんど変化がないはずです、、

//サブプロセス1個の場合 1周の所要時間:0.7286965847015381 main process... 1周の所要時間:0.45372629165649414 main process... 1周の所要時間:0.5691251754760742 main process... sub process... 1周の所要時間:0.5207698345184326
//サブプロセス3個の場合 1周の所要時間:1.465956449508667 main process... 1周の所要時間:1.0600461959838867 main process... 1周の所要時間:1.0374970436096191 main process... sub process... 1周の所要時間:1.293185949325561

該当のソースコード

python

1import os 2import datetime 3import json 4import time 5import asyncio 6from multiprocessing import Process, Queue, freeze_support, set_start_method 7import sys 8import random 9 10 11def sub_process(q): 12 while q.qsize()!=0: 13 print('sub process...') 14 queue_data=q.get() 15 if queue_data=='sleep': 16 print('5秒待ちます...') 17 time.sleep(5) 18 else: 19 hoge.hoge(queue_data) # キューに入れたデータをcsvに変換して保存します 20 print('sub processを終了します.') 21 sys.exit(0) 22 23 24def main(q): 25 try: 26 while True: 27 print('main process...') 28 start = time.time() 29 fuga = fuga.fuga() #センサから値を取ってきます 30 31 q.put(fuga) 32 print(f'main process queue size: {q.qsize()}') 33 elapsed_time=time.time()-start 34 print(f'1周の所要時間:{elapsed_time}\n') 35 #time.sleep(2) 36 except KeyboardInterrupt: 37 print('プログラムを終了します.') 38 39 40if __name__ == '__main__': 41 print(f'使用可能なCPU数:{len(os.sched_getaffinity(0))}') 42 #freeze_support() 43 #set_start_method('spawn') 44 q=Queue() 45 q.put('sleep') 46 q.put('sleep') 47 q.put('sleep') 48 p_sub = Process(target=sub_process, args=(q,)) 49 p_subsub = Process(target=sub_process, args=(q,)) 50 p_subsubsub = Process(target=sub_process, args=(q,)) 51 p_main = Process(target=main, args=(q,)) 52 p_sub.start() 53 p_subsub.start() 54 p_subsubsub.start() 55 p_main.start() 56 p_main.join() 57 p_sub.join() 58 p_subsub.join() 59 p_subsubsub.join()

##環境
OS: Raspberrypi OS
デバイス: ラズパイ4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2021/06/08 01:40

遅延が生じるとはなにがどういうふうになるんでしょうか 意味不明です
aiai8976

2021/06/08 01:45

失礼しました。 追記したので、確認お願い致します。
quickquip

2021/06/08 03:03

できればそのまま実行できるコード(問題が明確になっている実証用のコード)がいいな、と感じました。 あと、multiprocessingの質問だと、OSの情報が必須かと思います。
quickquip

2021/06/08 03:15

> 平均的な所要時間が多くなってしまいます 手元の環境での結果でいいので、具体的に2個の時は○秒、3個の時は○秒、と書いた方がいいと思いました。 https://teratail.com/help/question-tips#questionTips3-4-1 > 実際に起きた結果を示しましょう。例えば、「○○というエラーが表示された」、「レイアウトがこのように崩れてしまった」等です。あなたの想像ではなく、実際に起きたことを述べましょう。
aiai8976

2021/06/08 04:35

正しい意見ありがとうございます。 改めて追加してみたので確認お願い致します。
jbpb0

2021/06/08 06:15

もっと時間がかかるような処理で比較したら、差が縮まりませんか? (差というか比というか)
aiai8976

2021/06/08 08:59

mainの方のプログラムをなるべく早く回したくて、取得したデータを一旦キューに入れるようにしています。 だから、時間がかかるような処理で比較するのはあまり意味がないのかなと思うのですが、どうでしょうか?
quickquip

2021/06/08 09:04

現象から逆算すると fuga.fuga() #センサから値を取ってきます にディスクI/Oがないか、とか気になりますね……
jbpb0

2021/06/08 09:41

プロセス数を変えた場合の比較では無く、ジョブの重たさを変えた場合の比較ですが、 http://551sornwmc.blog109.fc2.com/blog-entry-377.html?sp によると、並列化無しでトータル計算時間が1.2秒の場合は、マルチプロセスでトータル2.1秒かかっていて、マルチプロセスが負けてます 並列化無しでトータル13.5秒の場合で、マルチプロセスでトータル10.6秒でかろうじて逆転してますが、たいして高速にはなってません もっと重たいジョブじゃないと、並列化の恩恵は感じられないでしょう このことから、並列化したい計算以外の部分(プロセスの起動等)で結構時間かかってて、それが相対的に少なくなるような条件(並列化したい計算の比率が高い)にしないと、マルチプロセスの優位性が発揮されないのだと思います 上記はWin PCの場合で、ラズパイのCPUだと、逆転する計算時間はもっと長いかも ここからは、上記からの想像なので、外れてるかもしれません 質問者さんが確認してる条件は、プロセスの計算時間がとても短いことから、上記のマルチプロセスに優位性があまり無い、本当に並列化したい計算以外の部分の比率が高い条件になっているのだろうと思います プロセス数を増やしたらプロセスあたりの時間が増えているのは、並列化したい計算以外の部分(プロセスの起動等)が、もしかしたら並列化が難しくて、プロセス数を増やすと不利になっているのかも、と思いまして、時間がかかる処理で比較したら、と書きました しかしながら、実際に並列化して高速化したい処理が時間がかからないものなら、時間がかかる処理で試すのは意味ないですね
aiai8976

2021/06/09 01:41

並列化で恩恵を受けるのはかなり時間の必要な処理に関してなんですね。 丁寧な説明ありがとうございました。 並列化以外で自分がやりたいことができないか検討してみます。
guest

回答1

0

ベストアンサー

並列処理の実行性能は、(仮想)CPUコアの数だけの問題ではありません。

L2キャッシュ(データの局所性)
メモリ量 (ページングの頻度)
ストレージIO (バス幅、機器の速度、連続アクセスかランダムアクセスか)
ネットワーク (DBなど他サーバとの接続)

などが影響しますので、hoge.hogeやfuga.fugaが何をやるかしだいです。

CPU数と言っているものも、インテルのハイパースレッディングのように見かけのコア数は多くても演算パイプを共用している場合にはそこまでの性能は出ないアプリが多いです。

投稿2021/06/08 04:26

ppaul

総合スコア24666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aiai8976

2021/06/08 04:38

回答ありがとうございます。 簡単にやっていることを追記させていただきました。 それらの処理は変えられない場合、完全な並列処理は難しいですか? また、他のやり方を知っていたりしますか?
ppaul

2021/06/08 15:35

並列実行するようにプログラムを書き換えるれば「完全な並列処理」はできますが、「逐次実行ようり高速な並列処理」ができるようなアプリケーション分野は、100分野に1本見つかればいいほうです。そしてそういうものはたいていは100時間かかるものを1時間に縮めたというようなものです。 数秒の処理を半分にできるというようなアプリケーションはほぼ見つからないと思ってください。
aiai8976

2021/06/09 01:42

よくわかりました。 丁寧な説明ありがとうございました。 並列化以外で自分のやりたいことが実現できないか検討してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問