gpt4 book ai didi

python - 在 Python 中写入共享内存非常慢

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:39:13 25 4
gpt4 key购买 nike

我使用 python.multiprocessing.sharedctypes.RawArray 在多个进程之间共享大型 numpy 数组。而且我注意到,当这个数组很大(> 1 或 2 Gb)时,它的初始化速度变得非常慢,而且读/写速度也慢得多(并且读/写时间不可预测,有时很快,有时非常非常慢)。

我制作了一个小示例脚本,它只使用一个进程,初始化一个共享数组并多次写入它。并测量执行这些操作的时间。

import argparse
import ctypes
import multiprocessing as mp
import multiprocessing.sharedctypes as mpsc
import numpy as np
import time

def main():
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-c', '--block-count', type=int, default=1,
help='Number of blocks to write')
parser.add_argument('-w', '--block-width', type=int, default=20000,
help='Block width')
parser.add_argument('-d', '--block-depth', type=int, default=15000,
help='Block depth')
args = parser.parse_args()
blocks = args.block_count
blockwidth = args.block_width
depth = args.block_depth
start = time.perf_counter()
shared_array = mpsc.RawArray(ctypes.c_uint16, blocks*blockwidth*depth)
finish = time.perf_counter()
print('Init shared array of size {:.2f} Gb: {:.2f} s'.format(blocks*blockwidth*depth*ctypes.sizeof(ctypes.c_uint16)/1024/1024/1024, (finish-start)))
numpy_array = np.ctypeslib.as_array(shared_array).reshape(blocks*blockwidth, depth)
start = time.perf_counter()
for i in range(blocks):
begin = time.perf_counter()
numpy_array[i*blockwidth:(i+1)*blockwidth, :] = np.ones((blockwidth, depth), dtype=np.uint16)
end = time.perf_counter()
print('Write = %.2f s' % (end-begin))
finish = time.perf_counter()
print('Total time = %.2f s' % (finish-start))

if __name__ == '__main__':
main()

当我运行这段代码时,我在我的电脑上得到以下信息:

$ python shared-minimal.py -c 1
Init shared array of size 0.56 Gb: 0.36 s
Write = 0.13 s
Total time = 0.13 s
$ python shared-minimal.py -c 2
Init shared array of size 1.12 Gb: 0.72 s
Write = 0.12 s
Write = 0.13 s
Total time = 0.25 s
$ python shared-minimal.py -c 4
Init shared array of size 2.24 Gb: 5.40 s
Write = 1.17 s
Write = 1.17 s
Write = 1.17 s
Write = 1.57 s
Total time = 5.08 s

在最后一种情况下,当数组大小超过 2 Gb 时,初始化时间与数组大小非线性相关,并且将保存大小的切片分配给数组的速度要慢 5 倍以上。

我想知道为什么会这样。我正在使用 Python 3.5 在 Ubuntu 16.04 上运行脚本。我还通过使用 iotop 注意到,在初始化和写入阵列时,有一个与共享阵列大小相同的磁盘写入事件,但我不确定是否创建了真实文件或者它仅在- 内存操作(我想应该是)。通常,在大型共享阵列的情况下,我的系统也会变得响应速度较慢。没有交换,使用 topipcs -muvmstat 检查。

最佳答案

经过更多研究后,我发现 python 实际上在 /tmp 中创建以 pymp- 开头的文件夹,尽管使用文件查看器看不到其中的文件,它看起来非常像 /tmp/ 被 python 用于共享内存。刷新文件现金时,性能似乎在下降。

最终可行的解决方案是将 /tmp 挂载为 tmpfs:

sudo mount -t tmpfs tmpfs /tmp

并且,如果使用最新的 docker,通过向 docker run 命令提供 --tmpfs/tmp 参数。

这样做后,读写操作都在RAM中完成,性能快速稳定。

我仍然想知道为什么 /tmp 用于共享内存,而不是 /dev/shm 已经作为 tmpfs 并且应该用于共享内存。

关于python - 在 Python 中写入共享内存非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44747145/

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