並列計算(python multiprocessing)

並列計算を勉強しようと思いまして、pythonのmultiprocessingを触っております。 ただ、あまり並列計算用にコードを書き換えるということをしたくないので、何か簡単な方法はないかと探しておりました。 そんな時に目についたのがこの記事。

Poolのmapメソッドを使えば、簡単に並列計算ができるらしいが、複数の引数を取る関数(例えば以下)に適用しようとするとエラーが出る。 そこで、これを解決しようという内容だ。

def myfunc(a, b):
    return a*b

これはリスト内包表記とどちらが早いのか、やってみた。 コードは以下

def argwrapper(args):
    return args[0](*args[1:])

def myfunc(a, b):
    return a*b

if __name__ == '__main__':
    from time import time

    i = 100
    j = 100

    #usual way
    start = time()
    results = [myfunc(a, b) for a in xrange(1, i) for b in xrange(1, j)]
    end = time()
    print "comprehension:", end-start

    #multi processing

    from multiprocessing import Pool
    p = Pool(8)
    func_args = [(myfunc, a, b) for a in xrange(1, i) for b in xrange(1, j)]
    start = time()
    results = p.map(argwrapper, func_args)
    end = time()
    print "multiprocessing:", end-start

結果が以下

comprehension:   0.00245380401611
multiprocessing: 0.00831413269043

おいおい、普通に内包表記の方が早いではないか…
しかも引数リストを作る時間まで合わせるととても使える代物ではない…
どうしたことか。処理に時間のかかるメソッドなら早いのかな?
というわけで以下のメソッドで再計測

def myfunc(a, b):
    for i in xrange(100000):
        pass

結果は以下

comprehension: 18.3397388458
multiprocessing: 5.15106010437

なんと!3分の一(の純情な感情)やないか!これは驚き。
処理の思いメソッドなら、並列計算の恩恵を受けることができるんですね。
いやぁ久々に震えました笑。どんどん並列化しよう。
今回はここまで。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中