我正在研究使用ctypes来使用C函数操作必须在16字节边界上对齐的SSE (__m128)数据。
我找不到一种简单的方法来控制ctypes分配的内存对齐,所以,现在,我让ctypes调用一个提供正确对齐的内存缓冲区的C函数。
我使用这种方法的问题是,我必须手动显式释放该内存,以防止它被泄露。
是否有一种方法来控制ctypes分配的内存对齐?或者是否有一种方法来注册一个清理函数来释放由ctypes调用的C函数分配的内存(除了标准的python操作符__del__) ?
最佳路径是什么
我已经花了一些时间来调查,我想出了一个函数,应该允许我分配任意对齐的内存与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
我认为c_ulonglong
(64位)必须是64位对齐的;这是一个开始。然后,文档建议您可以使用_pack_
来控制结构的对齐。这两个并不完全是您想要的,但是通过组合它们,您可以分配8字节对齐的无孔结构。
让我们假设一个结构体有3个8字节对齐的元素.v0
, .v1
, .v2
。使用addressof()
查看结构体是否为16字节对齐。如果是,使用.v0
和.v1
作为128位值;如果不是,使用.v1
和.v2
。