質問編集履歴

5 初心者マークをつけました

reishisu

reishisu score 21

2018/07/24 21:46  投稿

【Python】ProcessPoolExecutor について
### 前提・実現したいこと
現在、Pythonで画像のグレースケールに変換する処理を並列で実行しようとしています。
そこでconcurrent.futuresのProcessPoolExecutorでmax_workerに5コア以上入れた場合2〜4コアと比べてあまり高速化されてないでのですが、原因がわからず困っております。
他のサイトを見てみても5コア以上はそこまで高速化できてないようですが、それがなぜかまでは説明されておりませんでした、、、
なので、原因ともしうまく高速化出来るのであれば教えて頂きたいです。
また、同じ要領でThredPoolExecutorを利用した場合スレッドの本数を2〜40にしてもシングルスレッドの実行結果と変わらなかったのですがなぜマルチスレッドでは全く高速化出来なかったのかも合わせて質問さて頂きたいです。
今回初めて、マルチプロセスやマルチスレッドを触るので理解が甘いのと処理がおかしいところもあるかもしれないです。。。
### 該当のソースコード
```Python3
"""
並列で画像をモノクロにする
画像をコマンドライン引数で渡しておく
例)python ParallelMono.py 画像.pngとか
事前に
pip install opencv-python
pip install matplotlib
pip install futures
をしておく"""
# スレッドで並列化を利用する為に必要なモジュール
import concurrent.futures
# その他各ライブラリをインポート
import matplotlib.pyplot as plt
import numpy as np
import cv2
import common
import sys
import os
import time
# コンソールをクリア
os.system('clear')
# コマンドライン引数から画像を読み込む
img = common.getRGBImage( sys.argv[1] )
# 使用数を初期化
useThread = 1
useCPU = 1
def main():
# スレッドかCPUか選ぶ
msg = "マルチスレッドかマルチプロセスどちらにしますか?\n"\
"[1:マルチスレッド 2:マルチプロセス] : "
multchType = int( input(msg.format(os.cpu_count())) )
# 使用する数を選択
if multchType == 1:
useThread = int( input("使用するスレッドの数を入力してください : ") )
if useThread > 1:
mulchThread(useThread= useThread)
plt.imshow(img)
plt.show()
else:
print("0以下なので終了")
elif multchType == 2:
useCPU = int( input("使用するCPUのコアを入力してください[ 1 ~ {0} ] : ".format(os.cpu_count())) )
if useCPU >= 1 and useCPU <= os.cpu_count():
mulchProcess(useCPU= useCPU)
plt.imshow(img)
plt.show()
else:
print("選択の範囲外なので終了")
else:
print("どちらでもないので終了")
def changeToGray( number: int, width: np.ndarray ):
"""
並列化する処理
@param number (int) : このプロセスの番号
@param width (np.ndarray) : 横1行の配列[ [R, G, B], ・・・・ ,[R, G, B] ]
@return number (int) : このプロセスの番号
@return width (np.ndarray) : 引数で受け取った配列をグレースケールに変換した配列
"""
for pixel in width:
# グレースケールにするする処理
gray = int(pixel[0]*0.3) + int(pixel[1]*0.59) + int(pixel[2]*0.11)
pixel[0] = gray # Red
pixel[1] = gray # Green
pixel[2] = gray # Blue
return number, width
def mulchProcess(useCPU: int):
"""
マルチコアでプロセスを生成して実行させる処理
@param useCPU (int) : 使用するCPUのコア数
"""
print("")
start = time.time()
count = 0
print("{0}コアで処理を開始します!!".format(useCPU))
with concurrent.futures.ProcessPoolExecutor(max_workers=useCPU) as executer:
fs = [ executer.submit(changeToGray, i, width) for width, i in zip( img, range(len(img)) ) ]
for future in concurrent.futures.as_completed(fs):
line_number = future.result()[0]
gray_width = future.result()[1]
img[line_number] = gray_width
count += 1
common.progressBar(count, len(img))
print("\n終了しました!!")
print("かかった時間:{0}秒".format( time.time()-start ))
def mulchThread(useThread: int):
"""
スレッドを生成して実行させる処理
@param useThread (int) : 使用するスレッドの数
"""
print("")
start = time.time()
count = 0
print("{0}スレッドで処理を開始します!!".format(useThread))
with concurrent.futures.ThreadPoolExecutor(max_workers=useThread) as executer:
fs = [ executer.submit(changeToGray, i, width) for width, i in zip( img, range(len(img)) ) ]
for future in concurrent.futures.as_completed(fs):
line_number = future.result()[0]
gray_width = future.result()[1]
img[line_number] = gray_width
count += 1
common.progressBar(count, len(img))
print("\n終了しました!!")
print("かかった時間:{0}秒".format( time.time()-start ))
if __name__ == '__main__':
main()
```
### 試したこと
色々、コアの数を変更したりスレッドを利用したりしてみましたがなかなか成果か現れません。
### 補足情報(FW/ツールのバージョンなど)
[実行環境]
MacBook Pro (15-inch, 2016)
プロセッサ : 2.6 GHz Intel Core i7 ( 4コア8スレッド )
メモリ : 16 GB 2133 MHz LPDDR3
Python 3.6.4
[実行結果]
1コア:93.36475276947021秒 100%
2コア:45.95268726348877秒  約203%
3コア:32.04803204536438秒  約291%
4コア:25.691081047058105秒  約363%
5コア:25.711262941360474秒 約363%
6コア:24.469857692718506秒 約381%
7コア:23.86842966079712秒 約391%
8コア:23.69063401222229秒 約394%
  • Python

    11763 questions

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

  • Python 3.x

    9853 questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

4 実行環境の説明に誤りがありましたので修正しました

reishisu

reishisu score 21

2018/07/23 06:54  投稿

【Python】ProcessPoolExecutor について
### 前提・実現したいこと
現在、Pythonで画像のグレースケールに変換する処理を並列で実行しようとしています。
そこでconcurrent.futuresのProcessPoolExecutorでmax_workerに5コア以上入れた場合2〜4コアと比べてあまり高速化されてないでのですが、原因がわからず困っております。
他のサイトを見てみても5コア以上はそこまで高速化できてないようですが、それがなぜかまでは説明されておりませんでした、、、
なので、原因ともしうまく高速化出来るのであれば教えて頂きたいです。
また、同じ要領でThredPoolExecutorを利用した場合スレッドの本数を2〜40にしてもシングルスレッドの実行結果と変わらなかったのですがなぜマルチスレッドでは全く高速化出来なかったのかも合わせて質問さて頂きたいです。
今回初めて、マルチプロセスやマルチスレッドを触るので理解が甘いのと処理がおかしいところもあるかもしれないです。。。
### 該当のソースコード
```Python3
"""
並列で画像をモノクロにする
画像をコマンドライン引数で渡しておく
例)python ParallelMono.py 画像.pngとか
事前に
 pip install opencv-python
 pip install matplotlib
 pip install futures
をしておく"""
# スレッドで並列化を利用する為に必要なモジュール
import concurrent.futures
# その他各ライブラリをインポート
import matplotlib.pyplot as plt
import numpy as np
import cv2
import common
import sys
import os
import time
# コンソールをクリア
os.system('clear')
# コマンドライン引数から画像を読み込む
img = common.getRGBImage( sys.argv[1] )
# 使用数を初期化
useThread = 1
useCPU = 1
def main():
   # スレッドかCPUか選ぶ
   msg = "マルチスレッドかマルチプロセスどちらにしますか?\n"\
         "[1:マルチスレッド 2:マルチプロセス] : "
   multchType = int( input(msg.format(os.cpu_count())) )
   # 使用する数を選択
   if multchType == 1:
       useThread = int( input("使用するスレッドの数を入力してください : ") )
       if useThread > 1:
           mulchThread(useThread= useThread)
           plt.imshow(img)
           plt.show()
       else:
           print("0以下なので終了")
   elif multchType == 2:
       useCPU = int( input("使用するCPUのコアを入力してください[ 1 ~ {0} ] : ".format(os.cpu_count())) )
       if useCPU >= 1 and useCPU <= os.cpu_count():
           mulchProcess(useCPU= useCPU)
           plt.imshow(img)
           plt.show()
       else:
           print("選択の範囲外なので終了")
   else:
       print("どちらでもないので終了")
def changeToGray( number: int, width: np.ndarray ):
   """
   並列化する処理
   @param number (int)      : このプロセスの番号
   @param width (np.ndarray) : 横1行の配列[ [R, G, B], ・・・・ ,[R, G, B] ]
   @return number (int)      : このプロセスの番号
   @return width (np.ndarray) : 引数で受け取った配列をグレースケールに変換した配列
   """
   for pixel in width:
       # グレースケールにするする処理
       gray = int(pixel[0]*0.3) + int(pixel[1]*0.59) + int(pixel[2]*0.11)
       pixel[0] = gray # Red 
       pixel[1] = gray # Green
       pixel[2] = gray # Blue
   return number, width
def mulchProcess(useCPU: int):
   """
   マルチコアでプロセスを生成して実行させる処理
   @param useCPU (int) : 使用するCPUのコア数
   """
   print("")
   start = time.time()
   count = 0
   print("{0}コアで処理を開始します!!".format(useCPU))
   with concurrent.futures.ProcessPoolExecutor(max_workers=useCPU) as executer:
       fs = [ executer.submit(changeToGray, i, width) for width, i in zip( img, range(len(img)) ) ]
       for future in concurrent.futures.as_completed(fs):
           line_number = future.result()[0]
           gray_width = future.result()[1]
           img[line_number] = gray_width
           count += 1
           common.progressBar(count, len(img))
   print("\n終了しました!!")
   print("かかった時間:{0}秒".format( time.time()-start ))
def mulchThread(useThread: int):
   """
   スレッドを生成して実行させる処理
   @param useThread (int) : 使用するスレッドの数
   """
   print("")
   start = time.time()
   count = 0
   print("{0}スレッドで処理を開始します!!".format(useThread))
   with concurrent.futures.ThreadPoolExecutor(max_workers=useThread) as executer:
       fs = [ executer.submit(changeToGray, i, width) for width, i in zip( img, range(len(img)) ) ]
       for future in concurrent.futures.as_completed(fs):
           line_number = future.result()[0]
           gray_width = future.result()[1]
           img[line_number] = gray_width
           count += 1
           common.progressBar(count, len(img))
   print("\n終了しました!!")
   print("かかった時間:{0}秒".format( time.time()-start ))
if __name__ == '__main__':
   main()
```
### 試したこと
色々、コアの数を変更したりスレッドを利用したりしてみましたがなかなか成果か現れません。
### 補足情報(FW/ツールのバージョンなど)
[実行環境]
MacBook Pro (15-inch, 2016)
プロセッサ : 2.6 GHz Intel Core i7 ( 最大8コア )
プロセッサ : 2.6 GHz Intel Core i7 ( 4コア8スレッド )
メモリ : 16 GB 2133 MHz LPDDR3
Python 3.6.4
[実行結果]
1コア:93.36475276947021秒       100%
2コア:45.95268726348877秒  約203%
3コア:32.04803204536438秒  約291%
4コア:25.691081047058105秒  約363%
5コア:25.711262941360474秒   約363%
6コア:24.469857692718506秒   約381%
7コア:23.86842966079712秒     約391%
8コア:23.69063401222229秒     約394%
  • Python

    11763 questions

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

  • Python 3.x

    9853 questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

3 タイトルの書式を変更しました。

reishisu

reishisu score 21

2018/07/23 01:40  投稿

【Python】 ProcessPoolExecutor について
【Python】ProcessPoolExecutor について
### 前提・実現したいこと
現在、Pythonで画像のグレースケールに変換する処理を並列で実行しようとしています。
そこでconcurrent.futuresのProcessPoolExecutorでmax_workerに5コア以上入れた場合2〜4コアと比べてあまり高速化されてないでのですが、原因がわからず困っております。
他のサイトを見てみても5コア以上はそこまで高速化できてないようですが、それがなぜかまでは説明されておりませんでした、、、
なので、原因ともしうまく高速化出来るのであれば教えて頂きたいです。
また、同じ要領でThredPoolExecutorを利用した場合スレッドの本数を2〜40にしてもシングルスレッドの実行結果と変わらなかったのですがなぜマルチスレッドでは全く高速化出来なかったのかも合わせて質問さて頂きたいです。
今回初めて、マルチプロセスやマルチスレッドを触るので理解が甘いのと処理がおかしいところもあるかもしれないです。。。
### 該当のソースコード
```Python3
"""
並列で画像をモノクロにする
画像をコマンドライン引数で渡しておく
例)python ParallelMono.py 画像.pngとか
事前に
pip install opencv-python
pip install matplotlib
pip install futures
をしておく"""
# スレッドで並列化を利用する為に必要なモジュール
import concurrent.futures
# その他各ライブラリをインポート
import matplotlib.pyplot as plt
import numpy as np
import cv2
import common
import sys
import os
import time
# コンソールをクリア
os.system('clear')
# コマンドライン引数から画像を読み込む
img = common.getRGBImage( sys.argv[1] )
# 使用数を初期化
useThread = 1
useCPU = 1
def main():
# スレッドかCPUか選ぶ
msg = "マルチスレッドかマルチプロセスどちらにしますか?\n"\
"[1:マルチスレッド 2:マルチプロセス] : "
multchType = int( input(msg.format(os.cpu_count())) )
# 使用する数を選択
if multchType == 1:
useThread = int( input("使用するスレッドの数を入力してください : ") )
if useThread > 1:
mulchThread(useThread= useThread)
plt.imshow(img)
plt.show()
else:
print("0以下なので終了")
elif multchType == 2:
useCPU = int( input("使用するCPUのコアを入力してください[ 1 ~ {0} ] : ".format(os.cpu_count())) )
if useCPU >= 1 and useCPU <= os.cpu_count():
mulchProcess(useCPU= useCPU)
plt.imshow(img)
plt.show()
else:
print("選択の範囲外なので終了")
else:
print("どちらでもないので終了")
def changeToGray( number: int, width: np.ndarray ):
"""
並列化する処理
@param number (int) : このプロセスの番号
@param width (np.ndarray) : 横1行の配列[ [R, G, B], ・・・・ ,[R, G, B] ]
@return number (int) : このプロセスの番号
@return width (np.ndarray) : 引数で受け取った配列をグレースケールに変換した配列
"""
for pixel in width:
# グレースケールにするする処理
gray = int(pixel[0]*0.3) + int(pixel[1]*0.59) + int(pixel[2]*0.11)
pixel[0] = gray # Red
pixel[1] = gray # Green
pixel[2] = gray # Blue
return number, width
def mulchProcess(useCPU: int):
"""
マルチコアでプロセスを生成して実行させる処理
@param useCPU (int) : 使用するCPUのコア数
"""
print("")
start = time.time()
count = 0
print("{0}コアで処理を開始します!!".format(useCPU))
with concurrent.futures.ProcessPoolExecutor(max_workers=useCPU) as executer:
fs = [ executer.submit(changeToGray, i, width) for width, i in zip( img, range(len(img)) ) ]
for future in concurrent.futures.as_completed(fs):
line_number = future.result()[0]
gray_width = future.result()[1]
img[line_number] = gray_width
count += 1
common.progressBar(count, len(img))
print("\n終了しました!!")
print("かかった時間:{0}秒".format( time.time()-start ))
def mulchThread(useThread: int):
"""
スレッドを生成して実行させる処理
@param useThread (int) : 使用するスレッドの数
"""
print("")
start = time.time()
count = 0
print("{0}スレッドで処理を開始します!!".format(useThread))
with concurrent.futures.ThreadPoolExecutor(max_workers=useThread) as executer:
fs = [ executer.submit(changeToGray, i, width) for width, i in zip( img, range(len(img)) ) ]
for future in concurrent.futures.as_completed(fs):
line_number = future.result()[0]
gray_width = future.result()[1]
img[line_number] = gray_width
count += 1
common.progressBar(count, len(img))
print("\n終了しました!!")
print("かかった時間:{0}秒".format( time.time()-start ))
if __name__ == '__main__':
main()
```
### 試したこと
色々、コアの数を変更したりスレッドを利用したりしてみましたがなかなか成果か現れません。
### 補足情報(FW/ツールのバージョンなど)
[実行環境]
MacBook Pro (15-inch, 2016)
プロセッサ : 2.6 GHz Intel Core i7 ( 最大8コア )
メモリ : 16 GB 2133 MHz LPDDR3
Python 3.6.4
[実行結果]
1コア:93.36475276947021秒 100%
2コア:45.95268726348877秒  約203%
3コア:32.04803204536438秒  約291%
4コア:25.691081047058105秒  約363%
5コア:25.711262941360474秒 約363%
6コア:24.469857692718506秒 約381%
7コア:23.86842966079712秒 約391%
8コア:23.69063401222229秒 約394%
  • Python

    11763 questions

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

  • Python 3.x

    9853 questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

2 タイトルの書式を変更しました。

reishisu

reishisu score 21

2018/07/23 01:40  投稿

Python ProcessPoolExecutor について
【Python】 ProcessPoolExecutor について
### 前提・実現したいこと
現在、Pythonで画像のグレースケールに変換する処理を並列で実行しようとしています。
そこでconcurrent.futuresのProcessPoolExecutorでmax_workerに5コア以上入れた場合2〜4コアと比べてあまり高速化されてないでのですが、原因がわからず困っております。
他のサイトを見てみても5コア以上はそこまで高速化できてないようですが、それがなぜかまでは説明されておりませんでした、、、
なので、原因ともしうまく高速化出来るのであれば教えて頂きたいです。
また、同じ要領でThredPoolExecutorを利用した場合スレッドの本数を2〜40にしてもシングルスレッドの実行結果と変わらなかったのですがなぜマルチスレッドでは全く高速化出来なかったのかも合わせて質問さて頂きたいです。
今回初めて、マルチプロセスやマルチスレッドを触るので理解が甘いのと処理がおかしいところもあるかもしれないです。。。
### 該当のソースコード
```Python3
"""
並列で画像をモノクロにする
画像をコマンドライン引数で渡しておく
例)python ParallelMono.py 画像.pngとか
事前に
 pip install opencv-python
 pip install matplotlib
 pip install futures
をしておく"""
# スレッドで並列化を利用する為に必要なモジュール
import concurrent.futures
# その他各ライブラリをインポート
import matplotlib.pyplot as plt
import numpy as np
import cv2
import common
import sys
import os
import time
# コンソールをクリア
os.system('clear')
# コマンドライン引数から画像を読み込む
img = common.getRGBImage( sys.argv[1] )
# 使用数を初期化
useThread = 1
useCPU = 1
def main():
   # スレッドかCPUか選ぶ
   msg = "マルチスレッドかマルチプロセスどちらにしますか?\n"\
         "[1:マルチスレッド 2:マルチプロセス] : "
   multchType = int( input(msg.format(os.cpu_count())) )
   # 使用する数を選択
   if multchType == 1:
       useThread = int( input("使用するスレッドの数を入力してください : ") )
       if useThread > 1:
           mulchThread(useThread= useThread)
           plt.imshow(img)
           plt.show()
       else:
           print("0以下なので終了")
   elif multchType == 2:
       useCPU = int( input("使用するCPUのコアを入力してください[ 1 ~ {0} ] : ".format(os.cpu_count())) )
       if useCPU >= 1 and useCPU <= os.cpu_count():
           mulchProcess(useCPU= useCPU)
           plt.imshow(img)
           plt.show()
       else:
           print("選択の範囲外なので終了")
   else:
       print("どちらでもないので終了")
def changeToGray( number: int, width: np.ndarray ):
   """
   並列化する処理
   @param number (int)      : このプロセスの番号
   @param width (np.ndarray) : 横1行の配列[ [R, G, B], ・・・・ ,[R, G, B] ]
   @return number (int)      : このプロセスの番号
   @return width (np.ndarray) : 引数で受け取った配列をグレースケールに変換した配列
   """
   for pixel in width:
       # グレースケールにするする処理
       gray = int(pixel[0]*0.3) + int(pixel[1]*0.59) + int(pixel[2]*0.11)
       pixel[0] = gray # Red 
       pixel[1] = gray # Green
       pixel[2] = gray # Blue
   return number, width
def mulchProcess(useCPU: int):
   """
   マルチコアでプロセスを生成して実行させる処理
   @param useCPU (int) : 使用するCPUのコア数
   """
   print("")
   start = time.time()
   count = 0
   print("{0}コアで処理を開始します!!".format(useCPU))
   with concurrent.futures.ProcessPoolExecutor(max_workers=useCPU) as executer:
       fs = [ executer.submit(changeToGray, i, width) for width, i in zip( img, range(len(img)) ) ]
       for future in concurrent.futures.as_completed(fs):
           line_number = future.result()[0]
           gray_width = future.result()[1]
           img[line_number] = gray_width
           count += 1
           common.progressBar(count, len(img))
   print("\n終了しました!!")
   print("かかった時間:{0}秒".format( time.time()-start ))
def mulchThread(useThread: int):
   """
   スレッドを生成して実行させる処理
   @param useThread (int) : 使用するスレッドの数
   """
   print("")
   start = time.time()
   count = 0
   print("{0}スレッドで処理を開始します!!".format(useThread))
   with concurrent.futures.ThreadPoolExecutor(max_workers=useThread) as executer:
       fs = [ executer.submit(changeToGray, i, width) for width, i in zip( img, range(len(img)) ) ]
       for future in concurrent.futures.as_completed(fs):
           line_number = future.result()[0]
           gray_width = future.result()[1]
           img[line_number] = gray_width
           count += 1
           common.progressBar(count, len(img))
   print("\n終了しました!!")
   print("かかった時間:{0}秒".format( time.time()-start ))
if __name__ == '__main__':
   main()
```
### 試したこと
色々、コアの数を変更したりスレッドを利用したりしてみましたがなかなか成果か現れません。
### 補足情報(FW/ツールのバージョンなど)
[実行環境]
MacBook Pro (15-inch, 2016)
プロセッサ : 2.6 GHz Intel Core i7 ( 最大8コア )
メモリ : 16 GB 2133 MHz LPDDR3
Python 3.6.4  
[実行結果]
1コア:93.36475276947021秒       100%
2コア:45.95268726348877秒  約203%
3コア:32.04803204536438秒  約291%
4コア:25.691081047058105秒  約363%
5コア:25.711262941360474秒   約363%
6コア:24.469857692718506秒   約381%
7コア:23.86842966079712秒     約391%
8コア:23.69063401222229秒     約394%
  • Python

    11763 questions

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

  • Python 3.x

    9853 questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

1 誤字を修正しました。

reishisu

reishisu score 21

2018/07/23 01:38  投稿

Python ProcessPoolExecutor について
### 前提・実現したいこと
現在、Pythonで画像のグレースケールに変換する処理を並列で実行しようとしています。
そこでconcurrent.futuresのProcessPoolExecutorでmax_workerに5コア以上入れた場合2〜4コアと比べてあまり高速化されてないでのですが、原因がわからず困っております。
他のサイトを見てみても5コア以上はそこまで高速化できてないようですが、それがなぜかまでは説明されておりませんでした、、、
なので、原因ともしうまく高速化出来るのであれば教えて頂きたいです。
また、同じ要領でThredPoolExecutorを利用した場合スレッドの本数を2〜40にしてもシングルスレッドの実行結果と変わらなかったのですがなぜマルチスレッドでは全く高速化出来なかったのかも合わせて質問さて頂きたいです。
### 該当のソースコード
```Python3
"""
並列で画像をモノクロにする
画像をコマンドライン引数で渡しておく
例)python ParallelMono.py 画像.pngとか
事前に
 pip install opencv-python
 pip install matplotlib
 pip install futures
をしておく"""
# スレッドで並列化を利用する為に必要なモジュール
import concurrent.futures
# その他各ライブラリをインポート
import matplotlib.pyplot as plt
import numpy as np
import cv2
import common
import sys
import os
import time
# コンソールをクリア
os.system('clear')
# コマンドライン引数から画像を読み込む
img = common.getRGBImage( sys.argv[1] )
# 使用数を初期化
useThread = 1
useCPU = 1
def main():
   # スレッドかCPUか選ぶ
   msg = "マルチスレッドかマルチプロセスどちらにしますか?\n"\
         "[1:マルチスレッド 2:マルチプロセス] : "
   multchType = int( input(msg.format(os.cpu_count())) )
   # 使用する数を選択
   if multchType == 1:
       useThread = int( input("使用するスレッドの数を入力してください : ") )
       if useThread > 1:
           mulchThread(useThread= useThread)
           plt.imshow(img)
           plt.show()
       else:
           print("0以下なので終了")
   elif multchType == 2:
       useCPU = int( input("使用するCPUのコアを入力してください[ 1 ~ {0} ] : ".format(os.cpu_count())) )
       if useCPU >= 1 and useCPU <= os.cpu_count():
           mulchProcess(useCPU= useCPU)
           plt.imshow(img)
           plt.show()
       else:
           print("選択の範囲外なので終了")
   else:
       print("どちらでもないので終了")
def changeToGray( number: int, width: np.ndarray ):
   """
   並列化する処理
   @param number (int)      : このプロセスの番号
   @param width (np.ndarray) : 横1行の配列[ [R, G, B], ・・・・ ,[R, G, B] ]
   @return number (int)      : このプロセスの番号
   @return width (np.ndarray) : 引数で受け取った配列をグレースケールに変換した配列
   """
   for pixel in width:
       # グレースケールにするする処理
       gray = int(pixel[0]*0.3) + int(pixel[1]*0.59) + int(pixel[2]*0.11)
       pixel[0] = gray # Red 
       pixel[1] = gray # Green
       pixel[2] = gray # Blue
   return number, width
def mulchProcess(useCPU: int):
   """
   マルチコアでプロセスを生成して実行させる処理
   @param useCPU (int) : 使用するCPUのコア数
   """
   print("")
   start = time.time()
   count = 0
   print("{0}コアで処理を開始します!!".format(useCPU))
   with concurrent.futures.ProcessPoolExecutor(max_workers=useCPU) as executer:
       fs = [ executer.submit(changeToGray, i, width) for width, i in zip( img, range(len(img)) ) ]
       for future in concurrent.futures.as_completed(fs):
           line_number = future.result()[0]
           gray_width = future.result()[1]
           img[line_number] = gray_width
           count += 1
           common.progressBar(count, len(img))
   print("\n終了しました!!")
   print("かかった時間:{0}秒".format( time.time()-start ))
def mulchThread(useThread: int):
   """
   スレッドを生成して実行させる処理
   @param useThread (int) : 使用するスレッドの数
   """
   print("")
   start = time.time()
   count = 0
   print("{0}スレッドで処理を開始します!!".format(useThread))
   with concurrent.futures.ThreadPoolExecutor(max_workers=useThread) as executer:
       fs = [ executer.submit(changeToGray, i, width) for width, i in zip( img, range(len(img)) ) ]
       for future in concurrent.futures.as_completed(fs):
           line_number = future.result()[0]
           gray_width = future.result()[1]
           img[line_number] = gray_width
           count += 1
           common.progressBar(count, len(img))
   print("\n終了しました!!")
   print("かかった時間:{0}秒".format( time.time()-start ))
if __name__ == '__main__':
   main()
```
### 試したこと
色々、コアの数を変更したりスレッドを利用したりしてみましたがなかなか成果か現れません。
### 補足情報(FW/ツールのバージョンなど)
[実行環境]
MacBook Pro (15-inch, 2016)
プロセッサ : 2.6 GHz Intel Core i7 ( 最大8コア )
メモリ : 16 GB 2133 MHz LPDDR3
[実行結果]
1コア:93.36475276947021秒       100%
2コア:45.95268726348877秒  約203%
3コア:32.04803204536438秒  約291%
4コア:25.691081047058105秒  約363%
5コア:25.711262941360474秒   約363%
6コア:24.469857692718506秒   約381%
7コア:23.86842966079712秒     約391%
8コア:23.69063401222229秒     約394%
  • Python 3.x

    9853 questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • Python

    11763 questions

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

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る