Help us understand the problem. What is going on with this article?

Parallel Pythonを使ってRaspberry Pi 2 の4コアCPUを使いきってみる

More than 3 years have passed since last update.

動機

新発売のRaspberry Pi 2 はなんと4コアCPU。折角だから分散処理をさせて4コアをフルに使いきってみたい。

やったこと

分散処理フレームワークParallel Pythonを用いた簡単な分散処理プログラムを走らせ、旧モデルと新モデルの処理速度を比較してみた。
また、mpstatで各コアの使用率を確認した。

結論

旧モデルと比較して、4コア使い切ると約8.5倍、1コアだけでも約2.4倍高速、という結果になった。
4コア使いきった時、mpstatの結果も全コア100%となった。

所感

4コア使い切れたので満足である。
また、1コアだけでも十分速い事がわかった。デスクトップ画面やChromeブラウザの起動が2.2〜2.6倍程度早くなったという報告があるが、速度向上率が近いことから、1コア分の性能向上が大きく寄与しているのかもしれない。

実験方法と結果

分散処理の実行と処理時間測定

与えた処理

1からNまでの自然数のうち偶数の個数を数える。数え方は、一つ一つ2で割った余りを求めて判定していく。
1からNまでの自然数をk分割し、k個のコアにそれぞれを分担させることで分散処理する。
N/2をすれば一発で求まる問題だが、敢えてつまらない仕事をさせてしまうことを先にラズパイに謝っておく。

今回はN=1000万 とした。

ソースコード

pptest.py
# coding: UTF-8

import pp

# nがmの倍数かどうかを判断する
def ismultiples(n,m):
    return n % m == 0

# n1からn2まで(n2を含む)の自然数のうちmの倍数が何個あるか求める
def sum_multiples(n1,n2,m):
    cnt = 0
    for x in range(n1,n2+1):
        if ismultiples(x,m):
            cnt += 1
    return cnt

# 処理させるラズパイのIPアドレス
ppservers = ("192.168.1.241","192.168.1.241","192.168.1.241","192.168.1.241",) #4コア使用
# ppservers = ("192.168.1.241",) #1コア使用

# 自然数の最大値
N = 10000000
# 数えたい倍数
M = 2
# ノード数
num_node = len(ppservers)

# 接続先ノードを登録してサーバオブジェクトを生成
job_server = pp.Server(0, ppservers)
# タスクの生成
jobs = []
for i in range(num_node):
    # i番目のノードが扱う自然数の範囲を求める
    indSt = N/num_node*i+1
    if (i==num_node-1):
        indEnd = N
    else:
        indEnd = indSt+N/num_node-1
    # ノードにタスクを投げる
    jobs.append(job_server.submit(sum_multiples, (indSt, indEnd, M), (ismultiples,), ("math",)))
    print("task%d args:(%d,%d,%d)" % (i,indSt,indEnd,M))  

# 実行結果を回収. sum_mutiples()の戻り値を取得するイメージ.
# ノードでの処理がまだ終わっていない時は、ここの処理は終わるまでブロックされる.
result = 0;
for i in range(num_node):
    result += jobs[i]()

# 結果を表示
print "%d以下の自然数のうち %dの倍数の数 = %d" % (N, M, result)
job_server.print_stats()

ソースコード上のポイント

ppserversに同じIPアドレスを4つ記述している。こうすることで同一ラズパイに4分割したタスクを投げる事になり、4コアをフルに使う事ができる。1コアしか使わないときは、1つだけ記述する。
もし、複数台のラズパイで分散処理させるときは、ここに各ラズパイのIPアドレスをセットすればよい。

Parallel Python のインストール

  1. Parallel Pythonのサイト からpp-1.6.4.tar.gzをダウンロードして解凍する
  2. 解凍した先のフォルダに移動
  3. インストール
    > python setup.py

スクリプトの実行

  1. 処理を受け付けるサーバを起動する
    > ppserver.py &
  2. 記述したスクリプトpptest.pyを実行する
    > python pptest.py

実行結果

実行環境 処理時間 [sec] 速度向上率 ※1
旧モデル (Raspberry Pi B+) 48.7 -
新モデル (Raspberry Pi 2 B) 1コア使用 20.1 2.4
新モデル (Raspberry Pi 2 B) 4コア使用 5.7 8.5

※1 速度向上率=旧モデル処理時間/新モデル処理時間

スクリプトの出力は以下のとおり

旧モデル (Raspberry Pi B+)

task0 args:(1,10000000,2)
10000000以下の自然数のうち 2の倍数の数 = 5000000
Job execution statistics:
job count | % of all jobs | job time sum | time per job | job server
1 | 100.00 | 48.4202 | 48.420249 | 192.168.1.241:60000
Time elapsed since server creation 48.7006518841
0 active tasks, 0 cores

新モデル (Raspberry Pi 2 B) 1コアのみ使用

task0 args:(1,10000000,2)
10000000以下の自然数のうち 2の倍数の数 = 5000000
Job execution statistics:
job count | % of all jobs | job time sum | time per job | job server
1 | 100.00 | 19.6110 | 19.610974 | 192.168.1.241:60000
Time elapsed since server creation 20.0955970287
0 active tasks, 0 cores

新モデル (Raspberry Pi 2 B) 4コア使用

task0 args:(1,2500000,2)
task1 args:(2500001,5000000,2)
task2 args:(5000001,7500000,2)
task3 args:(7500001,10000000,2)
10000000以下の自然数のうち 2の倍数の数 = 5000000
Job execution statistics:
job count | % of all jobs | job time sum | time per job | job server
4 | 100.00 | 20.6152 | 5.153800 | 192.168.1.241:60000
Time elapsed since server creation 5.68198180199
0 active tasks, 0 cores

mpstatで各コアのCPU使用率を見てみる

インストール

sudo apt-get install sysstat

実行

1秒間隔で10回測定するときは次のようにする
mpstat -P ALL 1 10

別ターミナルでmpstatを動かしながら、上記のスクリプトを実行してみた。

実行結果

旧モデル (Raspberry Pi B+)

1コアしかないので、CPU番号は0しかない。%usrが100になっている。

22:30:56 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
22:30:57 all 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
22:30:57 0 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

新モデル (Raspberry Pi 2 B) 1コアのみ使用

4コアあるのでCPU番号が0〜3まである。CPU3だけが100%、それ以外は0%になっている。allは1/4で25.0%となっている。

22:35:54 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
22:35:55 all 25.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 75.00
22:35:55 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
22:35:55 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
22:35:55 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
22:35:55 3 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

新モデル (Raspberry Pi 2 B) 4コア使用

4コア全部が100%になっている。満足。

22:22:11 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
22:22:12 all 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
22:22:12 0 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
22:22:12 1 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
22:22:12 2 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
22:22:12 3 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

akidn8
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away