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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NASM ctypes SIMD - 如何访问返回到ctypes的128位数组?相关的知识,希望对你有一定的参考价值。

我有一个由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位整数?

答案

您可以生成包含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'xffxeexddxccxbbxaax00x00x00x00x00x00x00x00x00x00x00'

(注意:缓冲区以空值终止,这就是17字节的原因)

将此可写缓冲区传递给您的函数,该函数可以将结果写回同一个缓冲区。返回时,使用以下命令转换回Python整数:

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

以上是关于NASM ctypes SIMD - 如何访问返回到ctypes的128位数组?的主要内容,如果未能解决你的问题,请参考以下文章

NASM:如何正确访问 ssd 驱动器?

x86 NASM 使用 printf 打包双打

NASM直接访问声卡(无操作系统)

Python - ctypes - 如何调用函数和访问结构字段?

Python/Windows/ctypes:调用 WaitForMultipleObjects 后如何获取进程返回状态?

我应该如何注释在 Python 中返回 ctypes 数组的函数?