gpt4 book ai didi

python - 为什么 multiprocessing.sharedctypes 赋值这么慢?

转载 作者:太空狗 更新时间:2023-10-29 21:28:22 27 4
gpt4 key购买 nike

这里有一些基准代码来说明我的问题:

import numpy as np
import multiprocessing as mp
# allocate memory
%time temp = mp.RawArray(np.ctypeslib.ctypes.c_uint16, int(1e8))
Wall time: 46.8 ms
# assign memory, very slow
%time temp[:] = np.arange(1e8, dtype = np.uint16)
Wall time: 10.3 s
# equivalent numpy assignment, 100X faster
%time a = np.arange(1e8, dtype = np.uint16)
Wall time: 111 ms

基本上我希望在多个进程之间共享一个 numpy 数组,因为它很大且只读。 This method效果很好,没有制作额外的副本,并且进程的实际计算时间很好。但是创建共享数组的开销是巨大的。

This post提供了一些关于为什么某些初始化数组的方法很慢的深刻见解(请注意,在上面的示例中,我使用的是更快的方法)。但是这篇文章并没有真正描述如何真正提高速度以达到类似 numpy 的性能。

有没有人对如何提高速度有任何建议?一些 cython 代码对分配数组有意义吗?

我在 Windows 7 x64 系统上工作。

最佳答案

由于 your second link 中给出的原因,这很慢,解决方案实际上非常简单:绕过(缓慢的)RawArray 切片分配代码,在这种情况下,它一次从源读取一个原始 C 值的效率很低数组创建一个 Python 对象,然后直接将其转换回原始 C 以存储在共享数组中,然后丢弃临时 Python 对象,并重复 1e8 次。

但是您不需要那样做;与大多数 C 级事物一样,RawArray 实现了缓冲协议(protocol),这意味着您可以将其转换为 memoryview, a view of the underlying raw memory that implements most operations in C-like ways。 ,如果可能,使用原始内存操作。所以不要这样做:

# assign memory, very slow
%time temp[:] = np.arange(1e8, dtype = np.uint16)
Wall time: 9.75 s # Updated to what my machine took, for valid comparison

使用 memoryview 将其作为原始字节类对象进行操作并以这种方式分配(np.arange 已经实现了缓冲协议(protocol),并且 memoryview 的切片赋值运算符无缝地使用了它):

# C-like memcpy effectively, very fast
%time memoryview(temp)[:] = np.arange(1e8, dtype = np.uint16)
Wall time: 74.4 ms # Takes 0.76% of original time!!!

注意,后者的时间是毫秒,不是秒;使用 memoryview 包装执行原始内存传输的复制只需要不到 1% 的时间来执行此操作,而 RawArray 默认情况下会执行此操作!

关于python - 为什么 multiprocessing.sharedctypes 赋值这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37705974/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com