Python中使用共享数组实现快速FFT的内存对齐

2024-03-29 06:59:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我写了一个图像处理应用程序,需要做很多事情,它必须尽可能多的实时。 数据的获取及其处理在单独的进程中运行(主要是出于性能原因)。数据本身相当大(2MPix 16位灰度图像)。在

我可以在进程之间共享数组,如本文所述: How do I pass large numpy arrays between python subprocesses without saving to disk?(我使用numpy共享包中的shmarray脚本)。 我可以在这些数据上执行提供的Numpy FFT而没有问题,但它相当慢。在

调用FFTW可能要快得多,但是为了充分利用它,我应该在内存对齐的数组上运行操作。在

问题是:有没有一种方法可以在进程之间创建和共享Numpy类型的数组,同时保证内存对齐?在


Tags: 数据内存图像numpy应用程序进程原因数组
2条回答

概括Sven的答案,此函数将返回任何numpy数组的对齐副本(如果需要):

import numpy as np
def aligned(a, alignment=16):
    if (a.ctypes.data % alignment) == 0:
        return a

    extra = alignment / a.itemsize
    buf = np.empty(a.size + extra, dtype=a.dtype)
    ofs = (-buf.ctypes.data % alignment) / a.itemsize
    aa = buf[ofs:ofs+a.size].reshape(a.shape)
    np.copyto(aa, a)
    assert (aa.ctypes.data % alignment) == 0
    return aa

要获得正确对齐的内存,最简单的标准技巧是分配超出需要的内存,如果对齐错误,则跳过前几个字节。如果我没记错的话,NumPy数组将始终是8字节对齐的,而FFTW需要16字节对齐才能达到最佳效果。因此,您只需多分配8个字节,如有必要,跳过前8个字节。在

编辑:这很容易实现。指向数据的指针在NumPy数组的ctypes.data属性中以整数形式提供。使用移位块可以通过切片、以不同的数据类型查看和重塑来实现,所有这些都不会复制数据,而是重用相同的buf。在

要分配一个16字节对齐的1000x1000 64位浮点数数组,我们可以使用以下代码:

m = n = 1000
dtype = numpy.dtype(numpy.float64)
nbytes = m * n * dtype.itemsize
buf = numpy.empty(nbytes + 16, dtype=numpy.uint8)
start_index = -buf.ctypes.data % 16
a = buf[start_index:start_index + nbytes].view(dtype).reshape(m, n)

现在,a是一个具有所需属性的数组,可以通过检查a.ctypes.data % 16是否确实是{}来验证。在

相关问题 更多 >