Apache 箭头、对齐和填充
Posted
技术标签:
【中文标题】Apache 箭头、对齐和填充【英文标题】:Apache arrow, alignment and padding 【发布时间】:2018-07-27 13:18:50 【问题描述】:我想使用 apache arrow,因为它使执行引擎能够利用现代处理器中包含的最新 SIMD(单输入多数据)操作,对分析数据处理进行原生矢量化优化。 (https://arrow.apache.org/)。
根据文档 (https://arrow.apache.org/docs/memory_layout.html),我了解到内存分配确保大约 64 字节对齐。
为了验证这 64 字节对齐,我使用 numpy 数组的 __array_interface__ 数据成员,它指向存储数组内容的数据区域,并在其上计算模 64。如果结果为 0,则内存地址至少对齐 64 字节。
当我执行下面的代码时,在我的系统(Fedora)上它似乎可以工作(模 64 的结果为零)但是当我在我同事的系统(Fedora)上执行相同的代码时它不起作用:模 64 的结果不为零。所以内存没有按 64 字节对齐。
请在此处找到我的代码:
import pyarrow as pa
tab=pa.array([[1, 2], [3, 4]])
panda_array=tab.to_pandas()
print('numpy address modulo 64 => '.format(panda_array.__array_interface__['data'][0], panda_array.__array_interface__['data'][0]%64))
感谢您的帮助。
【问题讨论】:
“不起作用”相当模糊。你到底得到了什么? minimal reproducible example. 我同意并道歉,我再次编辑我的帖子,希望它更清晰。 好多了,现在您有一个明确而具体的问题。如果我对 python 和 apache-arrow 有所了解,我可能会回答。 (我在 asm 和 C/C++ 中执行 SIMD)。 【参考方案1】:Arrow 中的内存是 64 字节对齐的,但在您的示例代码中,转换为 Pandas/NumPy 会生成数据副本,因为 Arrow 和 NumPy 中的嵌套列表数组的表示方式不同。在 Arrow 中,这是使用一个保存所有列表数据的缓冲区来完成的,而另一个缓冲区保存该数组中每个列表的偏移量。由于 NumPy 没有原生列表类型,它被表示为一个 NumPy 数组,其中包含其他 NumPy 数组作为元素。这些在第一个 NumPy 数组中表示为 Python 对象。
因此,使用 NumPy 函数,您会看到 NumPy 分配的内存,而不是 Arrow 分配的内存。因此,如果您的内存地址位于 64 字节边界上,那只是偶然。
在pyarrow
的下一个版本(0.9)中,将有一个buffers
属性来访问底层内存地址。然后,您应该能够直接检查 Arrow 内存是否分配在 64 字节对齐的地址上(应该总是如此)。
【讨论】:
在您的第一段中,您的意思是 64 byte 对齐吗? 8 字节对齐对大多数 SIMD 指令集没有多大帮助。 是的,我的意思是 64 字节。更正了答案。 在 Arrow 到 Pandas/NumPy 的转换过程中,有没有办法避免复制。 ? Arrow 文档指出了零拷贝过程:“Arrow 内存格式支持零拷贝读取,可实现闪电般快速的数据访问,而无需序列化开销” 很遗憾,由于 BlockManager 的内部结构,这只能在非常小的 Pandas 数据帧集上实现。对于 Pandas Series / NumPy 案例,许多转换是零拷贝的,但只有那些存在原生 NumPy 类型的转换。这些都是 int* 和 float* 类型以及 Pandas 中的分类类型。以上是关于Apache 箭头、对齐和填充的主要内容,如果未能解决你的问题,请参考以下文章