poster
2019-12-10, 16:49
有没有办法在同一台计算机上的MATLAB进程之间共享内存?
我正在多核计算机上运行几个MATLAB进程(如果重要,请运行Windows)。它们都使用相同的巨大输入数据。最好在内存中只有一个副本。
编辑:不幸的是,每个过程都需要访问整个巨大的输入数据,因此无法分割数据并解决问题。
回答:
如果进程仅读取数据, 而不修改数据,那么我相信您可以将输入数据放入一个大文件中,并使每个进程打开并从该文件中读取数据。每个进程都有其自己的文件位置指示器,可以将其移动到文件中的任何位置以读取所需的数据。我测试了两个MATLAB进程同时从一个文件中读取一百万次左右,并且一切似乎都工作正常。我只使用了基本文件I / O命令(在下面列出)。似乎您也可以使用MEMMAPFILE (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/memmapfile.html)来执行此操作,就像Fooz先生 (https://stackoverflow.com/questions/872209/sharing-memory-between-processes-matlab/872293#872293)在他的回答中提到的(和SCFrench在评论中)一样,假设您使用的是MATLAB版本R2008a或更高版本。
这是您可能会使用的一些文件I / O命令:
FOPEN (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/fopen.html) :每个进程将调用FOPEN并返回一个文件标识符,该标识符将在所有后续调用中使用。您可以以二进制或文本模式打开文件:
fid = fopen('data.dat','r'); % Binary mode fid = fopen('data.txt','rt'); % Text mode
FREAD (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/fread.html) :在二进制模式下,FREAD将从文件中读取数据:
A = fread(fid,20,'double'); % Reads 20 double-precision values
FSCANF (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/fscanf.html) :在文本模式下,FSCANF将读取文件中的数据并设置其格式:
A = fscanf(fid,'%d',4); % Reads 4 integer values
FGETL (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/fgetl.html) / FGETS (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/fgets.html) :在文本模式下,它们将从文件中读取整行。
FTELL (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/ftell.html) :这将告诉您当前文件位置指示符(从文件开头算起):
ftell(fid) ans = 8 % The position indicator is 8 bytes from the file beginning
FSEEK (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/fseek.html) :这会将文件位置指示器设置到文件中的所需位置:
fseek(fid,0,-1); % Moves the position indicator to the file beginning
FCLOSE (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/fclose.html) :每个进程都必须关闭对文件的访问(很容易忘记这样做):
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 诸如此类的同步机制(“ 锁 (http://en.wikipedia.org/wiki/Lock_(computer_science)) ”)有时可能会具有较高的开销,从而降低了代码的总体并行效率。
更多&回答... (https://stackoverflow.com/questions/872209)
我正在多核计算机上运行几个MATLAB进程(如果重要,请运行Windows)。它们都使用相同的巨大输入数据。最好在内存中只有一个副本。
编辑:不幸的是,每个过程都需要访问整个巨大的输入数据,因此无法分割数据并解决问题。
回答:
如果进程仅读取数据, 而不修改数据,那么我相信您可以将输入数据放入一个大文件中,并使每个进程打开并从该文件中读取数据。每个进程都有其自己的文件位置指示器,可以将其移动到文件中的任何位置以读取所需的数据。我测试了两个MATLAB进程同时从一个文件中读取一百万次左右,并且一切似乎都工作正常。我只使用了基本文件I / O命令(在下面列出)。似乎您也可以使用MEMMAPFILE (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/memmapfile.html)来执行此操作,就像Fooz先生 (https://stackoverflow.com/questions/872209/sharing-memory-between-processes-matlab/872293#872293)在他的回答中提到的(和SCFrench在评论中)一样,假设您使用的是MATLAB版本R2008a或更高版本。
这是您可能会使用的一些文件I / O命令:
FOPEN (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/fopen.html) :每个进程将调用FOPEN并返回一个文件标识符,该标识符将在所有后续调用中使用。您可以以二进制或文本模式打开文件:
fid = fopen('data.dat','r'); % Binary mode fid = fopen('data.txt','rt'); % Text mode
FREAD (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/fread.html) :在二进制模式下,FREAD将从文件中读取数据:
A = fread(fid,20,'double'); % Reads 20 double-precision values
FSCANF (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/fscanf.html) :在文本模式下,FSCANF将读取文件中的数据并设置其格式:
A = fscanf(fid,'%d',4); % Reads 4 integer values
FGETL (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/fgetl.html) / FGETS (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/fgets.html) :在文本模式下,它们将从文件中读取整行。
FTELL (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/ftell.html) :这将告诉您当前文件位置指示符(从文件开头算起):
ftell(fid) ans = 8 % The position indicator is 8 bytes from the file beginning
FSEEK (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/fseek.html) :这会将文件位置指示器设置到文件中的所需位置:
fseek(fid,0,-1); % Moves the position indicator to the file beginning
FCLOSE (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/fclose.html) :每个进程都必须关闭对文件的访问(很容易忘记这样做):
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 诸如此类的同步机制(“ 锁 (http://en.wikipedia.org/wiki/Lock_(computer_science)) ”)有时可能会具有较高的开销,从而降低了代码的总体并行效率。
更多&回答... (https://stackoverflow.com/questions/872209)