bugfix> pointers > 投稿

ctypesによって呼び出されるNASM 64 dllがあります。プログラムは2つの64ビット整数を乗算し、128ビット整数を返すため、xmm SIMD命令を使用しています。 10,000回ループし、その結果をmallocによって作成されたメモリバッファに保存します。

SIMD計算が実行されるNASMコードの一部は次のとおりです。

cvtsi2sd xmm0,rax
mov rax,[pcalc_result_0]
cvtsi2sd xmm1,rax
PMULUDQ xmm0,xmm1
lea rdi,[rel s_ptr] ; Pointer
mov rbp,qword[rdi]
mov rcx,[s_ctr]
;movdqa [rbp + rcx],xmm0
movdqu [rbp + rcx],xmm0
add rcx,16

movdqa命令は機能しません(align = 16ディレクティブでアセンブルされているにもかかわらず、プログラムがクラッシュします)。 movdqu命令は機能しますが、配列をctypesに戻すときに、戻りポインターを128ビットに変換する必要がありますが、128ビットのctypesデータ型はありません。 ctypesコードの関連部分は次のとおりです。

CallName.argtypes = [ctypes.POINTER(ctypes.c_double)]
CallName.restype = ctypes.POINTER(ctypes.c_int64)
n0 = ctypes.cast(a[0],ctypes.POINTER(ctypes.c_int64))
n0_size = int(a[0+1] / 8)
x0 = n0[:n0_size]

x0は、使用可能な形式に変換されたが、128ビットに変換されていない配列です。

に投稿がありますctypesを使用した128ビット整数の処理 これは、128ビット配列の受け渡しを処理しますが、出力は処理しません。

私の質問は:

-movdqaまたはmovdqu以外の命令を使用する必要がありますか?多くのSIMD命令のうち、これらが最も適切なようです。

-Pythonは任意のサイズまでの整数を処理できますが、明らかにctypesは処理できません。 64ビットより大きいctypesサイズがないときにctypesから128ビット整数を使用する方法はありますか?

回答 1 件
  • 128ビット整数を表す16バイトを含むバイト配列を生成し、バイト形式との間で変換できます。これは調整されていない可能性があるため、 movdqu を使用する必要があります 。 Pythonはメモリを管理できるように、戻り値の代わりに入出力パラメーターを使用します。

    >>> import ctypes
    >>> value = 0xaabbccddeeff
    >>> int128 = ctypes.create_string_buffer(value.to_bytes(16,'little',signed=True))
    >>> int128
    <ctypes.c_char_Array_17 object at 0x000001ECCB1D41C8>
    >>> int128.raw
    b'\xff\xee\xdd\xcc\xbb\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    
    

    (注:バッファーはヌルで終了します。これが17バイトの理由です)

    この書き込み可能なバッファを関数に渡すと、関数は結果を同じバッファに書き戻すことができます。戻ったら、次を使用してPython整数に戻します。

    >>> hex(int.from_bytes(int128.raw[:16],'little',signed=True))
    '0xaabbccddeeff'
    
    

あなたの答え