1. ホーム
  2. python

[解決済み] numpyをインポートすると、マルチプロセシングがシングルコアになるのはなぜですか?

2022-06-09 02:25:52

質問

私は、これが OS の問題としてカウントされるかどうかわかりませんが、誰かが物事の Python 側からいくつかの洞察を持っている場合に備えて、ここで質問してみようと思いました。

私はCPUに負荷のかかる for ループを joblib しかし、各ワーカー プロセスが異なるコアに割り当てられるのではなく、すべてのワーカー プロセスが同じコアに割り当てられてしまい、パフォーマンスが向上しないことがわかりました。

これは非常につまらない例ですが...。

from joblib import Parallel,delayed
import numpy as np

def testfunc(data):
    # some very boneheaded CPU work
    for nn in xrange(1000):
        for ii in data[0,:]:
            for jj in data[1,:]:
                ii*jj

def run(niter=10):
    data = (np.random.randn(2,100) for ii in xrange(niter))
    pool = Parallel(n_jobs=-1,verbose=1,pre_dispatch='all')
    results = pool(delayed(testfunc)(dd) for dd in data)

if __name__ == '__main__':
    run()

...そして、以下は htop に表示されます。

私は、Ubuntu 12.10 (3.5.0-26) を 4 コアのラップトップで実行しています。はっきりと joblib.Parallel は異なるワーカーのために別々のプロセスを生成していますが、これらのプロセスを異なるコアで実行させる方法はありますか?

どのように解決するのですか?

さらにググってみると、次のような答えが見つかりました。 ここで .

ある種の Python モジュール ( numpy , scipy , tables , pandas , skimage ...) は、インポート時にコア・アフィニティーを混乱させます。私が知る限り、この問題は、マルチスレッドのOpenBLASライブラリに対してリンクすることで特に発生するようです。

回避策は、タスクアフィニティをリセットすることです。

os.system("taskset -p 0xff %d" % os.getpid())

この行をモジュールのインポートの後に貼り付けると、私のサンプルはすべてのコアで動作するようになります。

私のこれまでの経験では、これは numpy のパフォーマンスに悪影響を与えていないように見えますが、これはおそらくマシンやタスクに特有のものでしょう。

更新しました。

また、OpenBLAS自体のCPUアフィニティリセットの動作を無効にする方法が2つあります。実行時に、環境変数 OPENBLAS_MAIN_FREE (または GOTOBLAS_MAIN_FREE ) のように、例えば

OPENBLAS_MAIN_FREE=1 python myscript.py

あるいは、OpenBLASをソースからコンパイルする場合は、ビルド時に Makefile.rule を編集して、次の行を含むようにします。

NO_AFFINITY=1