ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

用Python写入共享内存非常慢

2019-10-12 13:52:11  阅读:405  来源: 互联网

标签:python performance numpy linux shared-memory


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

当我运行此代码时,我在PC上得到以下信息:

$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注意到,在初始化并写入阵列时,磁盘写入活动的大小与共享阵列相同,但是我不确定是否创建了真实文件还是仅在内存中进行操作(我想是应该).通常,在大型共享阵列的情况下,我的系统的响应速度也会变慢.没有交换,请与top,ipcs -mu和vmstat检查.

解决方法:

经过更多研究后,我发现python实际上在/ tmp中创建了以pymp-开头的文件夹,尽管使用文件查看器在其中看不到任何文件,但是它看起来确实像/ tmp /被python用于共享内存.清空文件兑现后,性能似乎正在下降.

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

sudo mount -t tmpfs tmpfs /tmp

并且,如果使用最新的docker,请在docker run命令中提供–tmpfs / tmp参数.

完成此操作后,将在RAM中完成读/写操作,并且性能快速稳定.

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

标签:python,performance,numpy,linux,shared-memory
来源: https://codeday.me/bug/20191012/1900763.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有