2012-03-27 8 views
5

複数のことを行う必要がある画像処理アプリケーションを作成し、可能な限りリアルタイムで処理する必要があります。 データの取得とその処理は、主にパフォーマンス上の理由から、別々のプロセスで実行されます。データ自体はかなり大きい(2MPixの16ビットグレースケール画像)。共有アレーを使用したPythonでの高速FFTのメモリアラインメント

この投稿に記載されているように、プロセス間で配列を共有できます。 How do I pass large numpy arrays between python subprocesses without saving to disk?(私はnumpy-sharedパッケージのshmarrayスクリプトを使用しています)。 問題なくこれらのデータに付属のNumpy FFTを実行できますが、かなり遅いです。

FFTWを呼び出す方がはるかに高速ですが、メモリを十分に活用するためには、メモリを整列した配列に対して操作を実行する必要があります。

質問:Numpyのような配列をプロセス間で作成し共有する方法はありますか?つまり、同時にメモリが整列することが保証されていますか?

+1

あなたは何のPython FFTWバインディングを使用していますか?これらのバインディングは、正しく整列されたメモリブロックを割り当てる方法を提供するはずです。 –

+0

あなたは正しいですが、難しい部分は、それらの配列を複数のプロセス間で共有する必要があることです。私はこれらの関数が "共有"配列を作成しないことを確信しています。 – bubla

答えて

6

メモリを正しく整列させる最も簡単な方法は、必要以上にビットを割り当て、整列が間違っている場合は最初の数バイトをスキップすることです。私が正しく覚えていれば、NumPy配列は常に8バイトに整列され、FFTWでは16バイトの配列が必要です。したがって、必要以上に8バイトを割り当てるだけで、必要に応じて最初の8バイトはスキップします。

を編集するのは簡単です。データへのポインタは、NumPy配列のctypes.data属性の整数として使用できます。シフトされたブロックを使用することは、スライスしたり、別のデータ型として表示したり、再形成することで実現できます。これらはすべてデータをコピーするのではなく、同じbufを再利用します。

64ビット浮動小数点数の16バイト整列1000×1000の配列を割り当てるために、我々は、このコードを使用することができる:ここで

m = n = 1000 
dtype = numpy.dtype(numpy.float64) 
nbytes = m * n * dtype.itemsize 
buf = numpy.empty(nbytes + 16, dtype=numpy.uint8) 
start_index = -buf.ctypes.data % 16 
a = buf[start_index:start_index + nbytes].view(dtype).reshape(m, n) 

を、によって確認することができるようaは、所望の特性を有する配列でありますa.ctypes.data % 16が実際に0であることを確認してください。スヴェンの答えに

+0

例を挙げてください。たとえば、2次元複素数配列を扱いたいとしましょう。 – bubla

+0

元のポインタを解放/削除する必要があります。 –

+0

ここに2つの問題があります。 1.スキップするバイト数を調べるにはどうすればよいですか? 2.スキップを実行し、出力として希望の寸法の長方形の配列を取得するにはどうすればよいですか? 3. shmarrayモジュールにこの(おそらくかなり単純な)トリックを寄与することは意味をなさないと思いますか? (https://bitbucket.org/cleemesser/numpy-sharedmem/raw/5ca092f8222a/shmarray.py)? – bubla

1

一般化(必要な場合)、この関数は任意のnumpyの配列の整列のコピーを返します。

import numpy as np 
def aligned(a, alignment=16): 
    if (a.ctypes.data % alignment) == 0: 
     return a 

    extra = alignment/a.itemsize 
    buf = np.empty(a.size + extra, dtype=a.dtype) 
    ofs = (-buf.ctypes.data % alignment)/a.itemsize 
    aa = buf[ofs:ofs+a.size].reshape(a.shape) 
    np.copyto(aa, a) 
    assert (aa.ctypes.data % alignment) == 0 
    return aa 
関連する問題