3

私はここで少し頭を悩ませているかもしれませんが、Python で小さなバイオインフォマティクス プロジェクトに取り組んでいます。文字列セットの大規模な辞書 (RAM で約 2 ~ 3 GB) を分析するプログラムを並列化しようとしています。小さい辞書を使用している場合はマルチプロセッシング バージョンの方が高速ですが、大きな辞書を使用している場合はほとんどメリットがなく、ほとんどが遅いことがわかりました。私の最初の理論は、メモリが不足するとすべてが遅くなり、ボトルネックは仮想メモリへのスワップにあるというものでした。ただし、4*48GB の RAM を搭載したクラスターでプログラムを実行したところ、同じスローダウンが発生しました。私の 2 番目の理論は、特定のデータへのアクセスがロックされていたというものです。あるスレッドが別のスレッドで現在アクセスされている参照にアクセスしようとしている場合、そのスレッドは待機する必要がありますか? 操作したい辞書のコピーを作成してみましたが、しかし、それはひどく非効率的なようです。他に何が問題を引き起こしている可能性がありますか?

私のマルチプロセッシング方法は以下の通りです:

def worker(seqDict, oQueue):
     #do stuff with the given partial dictionary
     oQueue.put(seqDict)
oQueue = multiprocessing.Queue()
chunksize = int(math.ceil(len(sdict)/4)) # 4 cores
inDict = {}
i=0
dicts = list() 
for key in sdict.keys():
    i+=1
    if len(sdict[key]) > 0:
        inDict[key] = sdict[key]
    if i%chunksize==0 or i==len(sdict.keys()):
        print(str(len(inDict.keys())) + ", size")
        dicts.append(copy(inDict))
        inDict.clear()

for pdict in dicts:
    p =multiprocessing.Process(target = worker,args = (pdict, oQueue)) 
    p.start()
finalDict = {}

for i in range(4):
    finalDict.update(oQueue.get())
return finalDict
4

3 に答える 3

2

コメントで述べたように、またキンチが彼の回答で述べたように、サブプロセスに渡されたものはすべて、生成されたプロセスのローカルコンテキストで複製するために、ピクルス化およびアンピクルス化する必要があります。を使用multiprocess.Manager.dictしてsDict(これにより、プロセスがその上に作成されたオブジェクトをプロキシするサーバーを介して同じデータを共有できるようにする)、スライスインデックスを使用してプロセスをその共有sDictにスポーンする場合、スポーンに関連するシリアル化/逆シリアル化シーケンスを削減する必要があります。子プロセス。共有オブジェクトを操作するサーバー通信のステップでは、それでもボトルネックにぶつかる可能性があります。もしそうなら、あなたはあなたが真の共有メモリを使用できるようにあなたのデータを単純化することを検討する必要がありmultiprocess.Arrayますmultiprocess.Valuemultiprocess.sharedctypesプロセス間で共有するカスタムデータ構造を作成します。

于 2012-07-25T15:25:08.660 に答える
1

「文字列のセットの大きな辞書」からのデータは、ファイルまたは文字列に格納できるものに再フォーマットされ、mmapモジュールを使用してすべてのプロセス間で共有できるようになります。データを他のより好ましい形式に戻す必要がある場合、各プロセスで起動オーバーヘッドが発生する可能性がありますが、共有メモリ内のデータセット全体のどのサブセットで作業を行う必要があるかを示す何かを各プロセスに渡すことで、最小限に抑えることができます。そのプロセスに必要な部分を再構成します。

于 2012-07-25T15:39:30.017 に答える
0

キューを通過するすべてのデータは、pickle を使用してシリアライズおよびデシリアライズされます。大量のデータを渡す場合、これがボトルネックになる可能性があると思います。

データの量を減らしたり、共有メモリを利用したり、ac 拡張機能でマルチスレッド バージョンを作成したり、Python のマルチスレッド安全な実装 (おそらく jython または pypy; わかりません) を使用して、これのマルチスレッド バージョンを試すことができます。

ところで、マルチスレッドではなくマルチプロセッシングを使用しています。

于 2012-07-25T15:02:20.143 に答える