0

サーチャー クラスのパスである sklearn KDTree から多数のベクトルをクエリする必要があります。Python マルチプロセッシングを使用して並列でクエリを実行しようとしていますが、並列コードには単一バージョンとほぼ同じ (またはそれ以上) の時間がかかります。

import time, numpy as np
from sklearn.neighbors import KDTree
from multiprocessing import Pool

def glob_query(arg, **kwarg):
    return Searcher.query(*arg, **kwarg)

class Searcher:
    def __init__(self, N, D):
            self.kdt = KDTree(np.random.rand(N,D), leaf_size=30, metric="euclidean")

    def query(self, X):
            return self.kdt.query(X, k=5, return_distance=False)

    def query_sin(self, X):
            return [self.query(x) for x in X]

    def query_par(self, X):
            p = Pool(4)
            return p.map(glob_query, zip([self]*len(X), X))

if __name__=="__main__":
    N = 1000000     # Number of points to be indexed
    D = 50          # Dimensions
    searcher = Searcher(N, D)

    E = 100         # Number of points to be searched
    points = np.random.rand(E, D)

    # Works fine
    start = time.time()
    searcher.query_sin(points)
    print("Time taken - %f"%(time.time()-start))

    # Slower than single core
    start = time.time()
    print searcher.query_par(points)
    print("Time taken - %f"%(time.time()-start))

Time taken - 28.591089
Time taken - 36.920716

私は知りたいです

  • kd-tree が各ワーカー スレッド間でコピーされている場合
  • 検索を並列化する別の方法はありますか (pathos を使用しますか?)
4

3 に答える 3

2

私はpathos著者です。他の回答で述べたようにmultiprocessing、オブジェクトを新しいプロセスにコピーします。pathosのフォーク上に構築されているため、同じことが にも当てはまりmultiprocessingます。 pathos(1)より良いシリアライゼーションを提供し、(2)map複数の引数を取ることができるより柔軟で、(3)複数を開始するときのオーバーヘッドを取り除きますPool…しかし、これはあなたのケースのようには聞こえません.

個々の計算が本当に軽い場合は、スレッドを使用multiprocessing.dummyする方がよいでしょう。試してみて、速度が上がるかどうかを確認してください。インターフェイスは同じなので、コードを編集する必要はほとんどありません。また、他の人が示唆しているように、結果の順序を維持する必要がない場合、imap_unordered多くの場合mapPool.

多くの場合、最善の方法は、いくつかの種類の を試してmap、自分のケースでどれが最も速いかを確認することです。

于 2015-09-21T02:01:55.130 に答える