2016-11-11 18 views
0

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

谢谢!

回答

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”命令,你可以看到一个程序写入到使用在火炬的GPU也共享GPU内存(只是总量可达个人GPU内存,你可以看到它比Titan X拥有的12G内存更少)和python(它正在运行Tensorflow)。

而共享完成的底层机制?这是因为这两个火炬和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

enter image description here

这:

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,我做了一个 “混帐克隆https://github.com/pfnet/chainer”,然后例子/ MNIST目录跑 “蟒蛇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内存。

+0

谢谢!这可能是一个愚蠢的问题,但我仍然无法理解为什么“每个进程都会打开/ dev/nvidia0,之后没有其他进程可以打开它。”会使分享数组不可能。是否有可能每个进程打开/ dev/nvidia0并修改这个共享阵列,并让这个GPU进入其他进程(如单CPU中的多处理器)?当你说“此后没有其他进程可以打开它”时,你的意思是其他进程会永久卡住或者其他进程不能同时访问这个数组? – username123

+0

对不起,我的错误,现在我已经更新了答案,我希望它澄清一切。你现在有更好的成功机会。 –