Apache 箭头、对齐和填充

Apache arrow, alignment and padding

我想使用 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))

感谢您的帮助。

Arrow 中的内存是 64 字节对齐的,但在您的示例代码中,转换为 Pandas/NumPy 会生成数据副本,因为列表的嵌套数组在 Arrow 和 NumPy 中的表示方式不同。在 Arrow 中,这是使用一个缓冲区来完成的,该缓冲区保存所有列表的数据,而另一个缓冲区保存该数组中每个列表的偏移量。由于 NumPy 没有原生列表类型,它被表示为一个包含其他 NumPy 数组作为元素的 NumPy 数组。这些在第一个 NumPy 数组中表示为 Python 个对象。

因此使用 NumPy 函数,您会看到内存是由 NumPy 分配的,而不是由 Arrow 分配的。因此,如果您的内存地址位于 64 字节边界上,那只是偶然。

pyarrow的下一个版本(0.9)中,将有一个buffers 属性来访问底层内存地址。然后您应该能够直接检查 Arrow 内存是否分配在 64 字节对齐的地址上(它总是应该是)。