有没有办法在同一台计算机上的MATLAB进程之间共享内存?
我在多核计算机上运行几个MATLAB进程(如果有影响,运行Windows)。它们都使用相同的巨大输入数据。只在内存中保留一个副本会很好。
编辑:不幸的是,每个进程都需要访问整个巨大的输入数据,因此无法分割数据并解决问题。
有没有办法在同一台计算机上的MATLAB进程之间共享内存?
我在多核计算机上运行几个MATLAB进程(如果有影响,运行Windows)。它们都使用相同的巨大输入数据。只在内存中保留一个副本会很好。
编辑:不幸的是,每个进程都需要访问整个巨大的输入数据,因此无法分割数据并解决问题。
FOPEN: Each process will call FOPEN and return a file identifier it will use in all subsequent calls. You can open a file in either binary or text mode:
fid = fopen('data.dat','r'); % Binary mode
fid = fopen('data.txt','rt'); % Text mode
FREAD: In binary mode, FREAD will read data from the file:
A = fread(fid,20,'double'); % Reads 20 double-precision values
FSCANF: In text mode, FSCANF will read and format data from the file:
A = fscanf(fid,'%d',4); % Reads 4 integer values
FGETL/FGETS: In text mode, these will read whole lines from the file.
FTELL: This will tell you the current file position indicator in bytes from the beginning of the file:
ftell(fid)
ans =
8 % The position indicator is 8 bytes from the file beginning
FSEEK: This will set the file position indicator to a desired position in the file:
fseek(fid,0,-1); % Moves the position indicator to the file beginning
FCLOSE: Each process will have to close its access to the file (it's easy to forget to do this):
fclose(fid);
processDone = false;
while ~processDone,
if file_is_free(), % A function to check that other processes are not
% accessing the file
fid = fopen(fileName,'r+'); % Open the file
perform_process(fid); % The computation this process has to do
fclose(fid); % Close the file
processDone = true;
end
end
像这样的同步机制(“锁”)有时会产生很高的开销,从而降低代码的整体并行效率。
shmkey=12345;
sharedmatrix('clone',shmkey,X);
clear X;
spmd(8)
X=sharedmatrix('attach',shmkey);
% do something with X
sharedmatrix('detach',shmkey,X);
end
sharedmatrix('free',shmkey);
由于X存在于spmd(或parfor)的共享内存中,它没有加载时间和通信时间。从Matlab的角度来看,它是在spmd(或parfor)主体中新创建的变量。
祝好,
乔希
http://www.mathworks.com/matlabcentral/fileexchange/28572-sharedmatrix
编辑:将数据放入原始文件中,使用memmapfile(感谢SCFrench)。
============================================
没有真正的方法来解决这个问题。我的两个解决方案是:购买更多的RAM或将数据分页。最接近的方法是使用mex函数来分配共享内存,然后允许连续调用mex函数来提取更小的内存片段。您不希望将共享内存包装为Matlab数组(因为Matlab的内存模型无法很好地处理它)。我原本想建议看一下memmap,但显然存在问题。有时,您可以先运行一个Matlab程序来预处理或拆分数据成较小的块。然后每个Matlab进程都可以在自己的较小块上运行。这里有一个关于在Matlab中处理大型数据集的教程。可能不行,至少不能像处理常规MATLAB变量那样处理数据。
如果在Windows机器上,您可以创建一个COM/ActiveX包装器来访问共享数据。MATLAB允许通过actxserver
函数使用COM对象。但是,是否真的可以通过不同的进程“直接”访问数据还有疑问。在MATLAB和COM之间存在某种编组层,并且数据会被转换,至少根据Mathworks关于在MATLAB和COM之间交换数据的文档。如果我绝对需要在Windows机器上快速访问共享结构化数据,我可能会编写一些C++代码,使用Boost::interprocess中的共享内存,并在进程内部COM服务器(DLL)中封装对其的访问。我以前做过这个,尽管Boost::interprocess使它变得容易了很多,但仍然很麻烦。
Java方法(因为MATLAB是在Java之上运行)可能更有前途,但据我所知,没有任何像样的Java库可以提供对共享内存的访问。最接近的可能是通过java.nio.MappedByteBuffer使用内存映射文件,但那真的很低级。不过,如果您的数据相对“方形”(例如大型二维、三维或四维同质大小数据矩阵),这可能还可以。
您可以尝试使用HDF5文件,MATLAB内置HDF5支持,并且速度“相对”较快。但根据我的经验,HDF5似乎与并发性不太兼容。(至少当一个进程正在写入而其他进程正在读取时不兼容。如果有多个读者而没有写者,则可以正常工作。)