137

これがOSの問題としてもっと重要かどうかはわかりませんが、Pythonの終わりから誰かが何らかの洞察を持っている場合に備えて、ここで質問したいと思いました。

forを使用してCPUを多用するループを並列化しようとしましたが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このスクリプトの実行中に表示されるものは次のとおりです。

htop

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

4

3 に答える 3

163

もう少しグーグルした後、私はここで答えを見つけました。

numpy特定のPythonモジュール( 、、、、、 ...)がインポート時にコアアフィニティを混乱させるscipyことが判明しました。私の知る限り、この問題は、マルチスレッドのOpenBLASライブラリとリンクしていることが特に原因のようです。tablespandasskimage

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

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

モジュールのインポート後にこの行を貼り付けると、私の例はすべてのコアで実行されます。

htop_workaround

numpyこれまでの私の経験では、これはおそらくマシンおよびタスクに固有ですが、パフォーマンスに悪影響を与えることはないようです。

アップデート:

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

OPENBLAS_MAIN_FREE=1 python myscript.py

または、ソースからOpenBLASをコンパイルしている場合は、を編集しMakefile.ruleて行を含めることにより、ビルド時に永久に無効にすることができます。

NO_AFFINITY=1
于 2013-03-26T15:36:46.007 に答える
32

Python 3は、アフィニティを直接設定するためのメソッドを公開するようになりました

>>> import os
>>> os.sched_getaffinity(0)
{0, 1, 2, 3}
>>> os.sched_setaffinity(0, {1, 3})
>>> os.sched_getaffinity(0)
{1, 3}
>>> x = {i for i in range(10)}
>>> x
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> os.sched_setaffinity(0, x)
>>> os.sched_getaffinity(0)
{0, 1, 2, 3}
于 2015-07-12T17:56:27.500 に答える
15

これはUbuntu上のPythonで一般的な問題のようであり、以下に固有のものではありませんjoblib

CPUアフィニティを試してみることをお勧めします(taskset)。

于 2013-03-26T14:47:54.777 に答える