NASM ctypes SIMD - 如何访问返回到ctypes的128位数组?

问题描述 投票:0回答:1

我有一个由ctypes调用的NASM 64 dll。程序将两个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位。

Handling 128-bit integers with ctypes上有一篇文章涉及传入128位数组但未传出。

我的问题是:

- 我应该使用movdqa或movdqu以外的指令吗?在许多SIMD指令中,这些指示似乎是最合适的。

- Python可以处理任意大小的整数,但显然ctypes不能。当没有大于64位的ctypes大小时,有没有办法使用来自ctypes的128位整数?

pointers nasm ctypes
1个回答
1
投票

您可以生成包含16个字节的字节数组,表示128位整数,并转换为字节格式。这可能不对齐,所以你应该使用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'
© www.soinside.com 2019 - 2024. All rights reserved.