【问题标题】:define shared array in GPU memory with Python?用 Python 在 GPU 内存中定义共享数组?
【发布时间】:2016-11-11 22:58:03
【问题描述】:

我正在尝试通过 Python 使用由多个进程共享的数组。我通过使用multiprocessing.RawArray 定义数组并使用numpy.frombuffer() 使用数组来完成CPU 版本。当我尝试使用chainer.cuda.to_gpu() 将代码移植到 GPU 时,我发现每个进程只是将自己的副本复制到 GPU 内存空间中,并且数组没有共享。有谁知道有没有办法解决这个问题?

谢谢!

【问题讨论】:

    标签: python arrays numpy multiprocessing


    【解决方案1】:

    也许有办法解决你的问题。

    看看这里:

    sudo nvidia-smi
    Mon Nov 14 16:14:48 2016       
    +------------------------------------------------------+                       
    | NVIDIA-SMI 358.16     Driver Version: 358.16         |                       
    |-------------------------------+----------------------+----------------------+
    | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
    |===============================+======================+======================|
    |   0  GeForce GTX TIT...  Off  | 0000:01:00.0     Off |                  N/A |
    | 35%   76C    P2   111W / 250W |    475MiB / 12287MiB |     60%      Default |
    +-------------------------------+----------------------+----------------------+
    
    +-----------------------------------------------------------------------------+
    | Processes:                                                       GPU Memory |
    |  GPU       PID  Type  Process name                               Usage      |
    |=============================================================================|
    |    0     12235    C   /home/tteikhua/torch/install/bin/luajit        215MiB |
    |    0     27771    C   python                                         233MiB |
    +-----------------------------------------------------------------------------+
    

    使用“nvidia-smi”命令,可以看到在 Torch 中编写的使用 GPU 的程序也共享 GPU 内存(只需将单个 GPU 内存加起来,就可以看到它小于总数Titan X 拥有的 12G 内存)与 python(运行 Tensorflow)。

    以及共享的底层机制是如何完成的?这是因为 Torch 和 Tensorflow 都是用 CUDA 编译的,而且对 GPU 的访问也是共享的:

    ls -al /proc/12235/fd|grep nvidia0
    
    lrwx------ 1 tteikhua tteikhua 64 Nov 12 07:54 10 -> /dev/nvidia0
    lrwx------ 1 tteikhua tteikhua 64 Nov 12 07:54 11 -> /dev/nvidia0
    lrwx------ 1 tteikhua tteikhua 64 Nov 12 07:54 12 -> /dev/nvidia0
    lrwx------ 1 tteikhua tteikhua 64 Nov 12 07:54 4 -> /dev/nvidia0
    lrwx------ 1 tteikhua tteikhua 64 Nov 12 07:54 5 -> /dev/nvidia0
    lrwx------ 1 tteikhua tteikhua 64 Nov 12 07:54 6 -> /dev/nvidia0
    
    ls -al /proc/27771/fd|grep nvidia0
    
    lrwx------ 1 tteikhua tteikhua 64 Nov 14 15:51 10 -> /dev/nvidia0
    lrwx------ 1 tteikhua tteikhua 64 Nov 14 15:51 11 -> /dev/nvidia0
    lrwx------ 1 tteikhua tteikhua 64 Nov 14 15:51 15 -> /dev/nvidia0
    lrwx------ 1 tteikhua tteikhua 64 Nov 14 15:51 16 -> /dev/nvidia0
    lrwx------ 1 tteikhua tteikhua 64 Nov 14 15:51 17 -> /dev/nvidia0
    lrwx------ 1 tteikhua tteikhua 64 Nov 14 15:51 9 -> /dev/nvidia0
    

    那么如何实现呢?

    请看下面的图片:

    http://cuda-programming.blogspot.sg/2013/01/shared-memory-and-synchronization-in.html

    还有这个:

    https://www.bu.edu/pasi/files/2011/07/Lecture31.pdf

    这是 GPU 和 CPU 之间的共享。但是您的“共享”是两个不同的进程共享相同的 GPU 内存。这是可能的,如下所示:

    从 CUDA 示例修改 simpleMultiCopy:

    | Processes:                                                       GPU Memory |
    |  GPU       PID  Type  Process name                               Usage      |
    |=============================================================================|
    |    0     12235    C   /home/tteikhua/torch/install/bin/luajit        215MiB |
    |    0     27771    C   python                                         233MiB |
    |    0     31014    C   ./simpleMultiCopy                              238MiB |
    |    0     31021    C   ./simpleMultiCopy                              238MiB |
    |    0     31024    C   ./simpleMultiCopy                              238MiB |
    +-----------------------------------------------------------------------------+
    

    您会看到,运行同一程序的多个副本会导致 GPU 内存的并发共享,因为不同程序使用的单个内存加起来就是 GPU 上使用的总内存。

    对于chainer,我做了一个“git clone https://github.com/pfnet/chainer”,然后examples/mnist目录运行了两次“python train_mnist.py --gpu=0”,随后得到了这个:

    |   0  GeForce GTX 850M    Off  | 0000:01:00.0     Off |                  N/A |
    | N/A   64C    P0    N/A /  N/A |    322MiB /  4043MiB |     81%      Default |
    | Processes:                                                       GPU Memory |
    |  GPU       PID  Type  Process name                               Usage      |
    |=============================================================================|
    |    0     17406    C   python                                         160MiB |
    |    0     17414    C   python                                         160MiB |
    +-----------------------------------------------------------------------------+
    

    这意味着两个不同的进程共享相同的 GPU 内存。

    【讨论】:

    • 谢谢!这可能是一个愚蠢的问题,但我仍然不明白为什么“每个进程都会打开 /dev/nvidia0,然后没有其他进程可以打开它。”将无法共享数组。每个进程是否有可能打开 /dev/nvidia0 并修改这个共享数组并将这个 GPU 交给其他进程(比如单个 CPU 中的多处理)?当您说“此后没有其他进程可以打开它”时,您的意思是其他进程将永远卡住还是其他进程无法同时访问该数组?
    • 对不起,我的错误,现在我再次更新了答案,我希望它能澄清一切。你现在有更大的成功机会。
    猜你喜欢
    • 2018-05-31
    • 2017-08-28
    • 2012-06-24
    • 1970-01-01
    • 2018-07-07
    • 2011-05-22
    • 2015-02-16
    • 2020-04-06
    相关资源
    最近更新 更多