マルチスレッドとマルチプロセス
マルチスレッドとマルチプロセスは似ているようで違います。マルチプロセス間の実行中の値は、各プロセス間で別になっていますが、マルチスレッドの場合には変数を共用するのでちょっと注意が必要です。
実行環境
- cray xc40
- python 2.7.13
マルチプロセス
ここを参考に
03_multi.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# http://qiita.com/yubais/items/5a9d91fe03fe715b21d0
import multiprocessing as mp
import sys
L = 40000
proc=int(sys.argv[1])
# 各プロセスが実行する計算
def subcalc(queue, p):
subtotal = 0
# iの範囲を設定
ini = L * p / proc
fin = L * (p+1) / proc
for i in range(ini, fin):
for j in range(L):
subtotal += i * j
# キューにデータを送る
queue.put(subtotal)
# キューを作成
queue = mp.Queue()
# 8個のプロセスを用意
ps=[]
for i in range(proc):
ps.append(mp.Process(target=subcalc, args=(queue, i)))
# すべてを開始
for p in ps:
p.start()
# キューから結果を回収
total = 0
for i in range(proc):
total += queue.get() # キューに値が無い場合は、値が入るまで待機になる
print(total)
36プロセス
03_multi_36.sh
実行スクリプト
#!/bin/sh
#PBS -N 03_multi_36
#PBS -j oe
#PBS -l select=1:ncpus=36
#PBS -l place=scatter
#PBS -q SINGLE
if [ "${PBS_O_WORKDIR}" != "" ];then
cd ${PBS_O_WORKDIR}
fi
export OMP_NUM_THREADS=36
. ~/.bashrc
APRUN="aprun -n 1 -d $OMP_NUM_THREADS"
date
$APRUN python 03_multi.py 36
date
結果
2017年 6月 6日 火曜日 09:33:12 JST 639968000400000000 2017年 6月 6日 火曜日 09:33:17 JST
1プロセス
03_multi_1.sh
#!/bin/sh #PBS -N 03_multi_1 #PBS -j oe #PBS -l select=1:ncpus=1 #PBS -l place=scatter #PBS -q SINGLE if [ "${PBS_O_WORKDIR}" != "" ];then cd ${PBS_O_WORKDIR} fi export OMP_NUM_THREADS=1 . ~/.bashrc APRUN="aprun -n 1 -d $OMP_NUM_THREADS" date $APRUN python 03_multi.py 1 date
結果
2017年 5月 31日 水曜日 10:44:19 JST 639968000400000000 2017年 5月 31日 水曜日 10:45:35 JST
かなり速度が違います
マルチスレッド
ここを参考
03_multi.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# http://qiita.com/yubais/items/5a9d91fe03fe715b21d0
# http://kaworu.jpn.org/python/Pythonのマルチスレッドプログラミング
import threading
import sys
#http://ja.pymotw.com/2/Queue/
import Queue
L = 40000
proc=int(sys.argv[1])
# 各プロセスが実行する計算
def subcalc(queue, p):
subtotal = 0
# iの範囲を設定
ini = L * p / proc
fin = L * (p+1) / proc
for i in range(ini, fin):
for j in range(L):
subtotal += i * j
# キューにデータを送る
queue.put(subtotal)
# キューを作成
queue = Queue.Queue()
# 8個のプロセスを用意
ps=[]
for i in range(proc):
ps.append(threading.Thread(target=subcalc, args=(queue, i)))
# すべてを開始
for p in ps:
p.start()
p.join()
# キューから結果を回収
total = 0
for i in range(proc):
total += queue.get() # キューに値が無い場合は、値が入るまで待機になる
print(total)
36プロセス
04_thread_36.sh
実行スクリプト
#!/bin/sh
#PBS -N 04_thread_36
#PBS -j oe
#PBS -l select=1:ncpus=36
#PBS -l place=scatter
#PBS -q SINGLE
if [ "${PBS_O_WORKDIR}" != "" ];then
cd ${PBS_O_WORKDIR}
fi
export OMP_NUM_THREADS=36
. ~/.bashrc
APRUN="aprun -n 1 -d $OMP_NUM_THREADS"
date
$APRUN python 04_thread.py 36
date
結果
2017年 6月 6日 火曜日 09:39:57 JST 639968000400000000 2017年 6月 6日 火曜日 09:41:13 JST
1プロセス
04_thread_1.sh
実行スクリプト
#!/bin/sh
#PBS -N 04_thread_1
#PBS -j oe
#PBS -l select=1:ncpus=1
#PBS -l place=scatter
#PBS -q SINGLE
if [ "${PBS_O_WORKDIR}" != "" ];then
cd ${PBS_O_WORKDIR}
fi
export OMP_NUM_THREADS=1
. ~/.bashrc
APRUN="aprun -n 1 -d $OMP_NUM_THREADS"
date
$APRUN python 04_thread.py 1
date
結果
017年 6月 6日 火曜日 09:39:57 JST 639968000400000000 2017年 6月 6日 火曜日 09:41:13 JST