2011-12-28 7 views
4

私は、16バイトの境界に整列させる必要があるSSE(__m128)データを操作するC関数を使用するためにctypesを使用しています。python ctypesでの制御メモリの整列

ctypesによって割り当てられたメモリのアラインメントを制御する簡単な方法が見つかりませんでしたので、現在、私はctypesに、正しく整列されたメモリバッファを提供するC関数を呼び出しています。

私がこの方法で持っている問題は、手動でがリークするのを防ぐためにこのメモリを解放しなければならないということです。

ctypesによって割り当てられたメモリの配置を制御する方法はありますか? Ctypesによって呼び出されたC関数によって割り当てられたメモリを解放するためのクリーンアップ関数を登録する方法があります(標準のPython演算子__ del __から離れています)?

次の最適なパスは何ですか?

答えて

1

c_ulonglong(64ビット)は64ビットで整列している必要があります。それはスタートです。次に構造のアライメントを制御するdoc suggests that you can use _pack_。これらの2つはであり、正確にはではありませんが、それらを組み合わせることで、穴のない8バイトの整列した構造体を割り当てることができます。

8バイトのアライメントされた要素が3つある構造体を仮定しましょう。.v0.v1.v2。構造体が16バイトで整列されているかどうかを確認するには、addressof()を使用してください。使用している場合は、128ビット値には.v0.v1を使用してください。そうでない場合は、.v1.v2を使用してください。

+0

は '試みを_pack_'、そしてそれが1、2、4以外の値を扱うことができないようだ - それは16を扱うでしょう、それは私の答えになります。あなたの 'addressof'トリックについては、ありがとう、実際にはCのポインタ演算はトリックを行うことができます。私はこれよりも「クリーナー」にしたいと思います。 – rotoglup

2

私は調査に時間をかけてきましたが、ctypesがアライメントされていないメモリバッファに参照を保持しなければならないという事実に頼って、任意の位置合わせされたメモリをctypesに割り当てることができる関数を思いつきました。バッファ内の整列した位置から始まるインスタンスを有する。

これを実稼働環境でテストする必要があります。私はちょうど与えた

import ctypes 

def ctypes_alloc_aligned(size, alignment): 

    bufSize = size+(alignment-1) 
    raw_memory = bytearray(bufSize) 

    ctypes_raw_type = (ctypes.c_char * bufSize) 
    ctypes_raw_memory = ctypes_raw_type.from_buffer(raw_memory) 

    raw_address = ctypes.addressof(ctypes_raw_memory) 
    offset = raw_address % alignment 
    offset_to_aligned = (alignment - offset) % alignment 

    ctypes_aligned_type = (ctypes.c_char * (bufSize-offset_to_aligned)) 
    ctypes_aligned_memory = ctypes_aligned_type.from_buffer(raw_memory, offset_to_aligned) 

    return ctypes_aligned_memory 
+0

追加バッファを作成しない場合は、バッファを作成しますか?例:6192バイトのバッファ入力があり、私は8192バッファ出力を得ます(4096 * 2 = 8192バイトバッファに追加するため) –