Как я могу разделить память между процессами в MATLAB? - PullRequest
6 голосов
/ 16 мая 2009

Есть ли способ разделить память между процессами MATLAB на одном компьютере?

Я запускаю несколько процессов MATLAB на многоядерном компьютере (под управлением Windows, если это имеет значение). Все они используют одни и те же гигантские входные данные. Было бы неплохо иметь в памяти только одну его копию.

Редактировать: К сожалению, каждому процессу необходим доступ ко всем гигантским входным данным, поэтому нет способа разделить данные и решить проблему.

Ответы [ 4 ]

6 голосов
/ 18 мая 2009

Если процессы когда-либо только читают данные, но не изменяют их, то я считаю, что вы можете поместить свои входные данные в один большой файл, и каждый процесс будет открыт и прочитан из этого файла. Каждый процесс будет иметь свой собственный индикатор положения файла, который он может перемещать в любом месте файла, чтобы прочитать необходимые ему данные. Я проверил наличие двух процессов MATLAB, одновременно считывающих файл из миллиона или около того раз, и все, казалось, работало нормально. Я использовал только основные команды ввода / вывода файлов (перечислены ниже). Похоже, вы также можете сделать это, используя MEMMAPFILE , как Mr Fooz , упомянутый в его ответе (и SCFrench в комментарии), при условии, что у вас версия MATLAB R2008a или новее.

Вот некоторые команды ввода-вывода, которые вы, вероятно, будете использовать для этого:

  • FOPEN : каждый процесс вызывает FOPEN и возвращает идентификатор файла, который он будет использовать во всех последующих вызовах. Вы можете открыть файл в режиме двоичный или текст :

    fid = fopen('data.dat','r');   % Binary mode
    fid = fopen('data.txt','rt');  % Text mode
    
  • FREAD : в двоичном режиме FREAD будет считывать данные из файла:

    A = fread(fid,20,'double');  % Reads 20 double-precision values
    
  • FSCANF : в текстовом режиме FSCANF будет считывать и форматировать данные из файла:

    A = fscanf(fid,'%d',4);  % Reads 4 integer values
    
  • FGETL / FGETS : в текстовом режиме они читают целые строки из файла.

  • FTELL : будет указана текущая позиция файла в байтах от начала файла:

    ftell(fid)
    ans =
         8    % The position indicator is 8 bytes from the file beginning
    
  • FSEEK : Это установит индикатор положения файла на желаемую позицию в файле:

    fseek(fid,0,-1);  % Moves the position indicator to the file beginning
    
  • FCLOSE : каждому процессу придется закрыть доступ к файлу (это легко забыть сделать):

    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

Механизмы синхронизации, подобные этим (" lock ") могут иногда иметь большие накладные расходы, что снижает общую параллельную эффективность кода.

5 голосов
/ 27 августа 2010

Возможно, вы захотите оформить мою заявку на обмен файлами Matlab "sharedmatrix" # 28572. Это позволяет матрице Matlab существовать в разделяемой памяти, при условии, что вы используете некоторые разновидности Unix. Затем можно прикрепить общую матрицу в тело файла parfor или spmd, т. Е.

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).

Приветствия

Josh

http://www.mathworks.com/matlabcentral/fileexchange/28572-sharedmatrix

4 голосов
/ 16 мая 2009

РЕДАКТИРОВАТЬ: Поместить данные в сырой файл и использовать memmapfile (спасибо SCFrench).

============================================

Нет, нет реального способа сделать это.

Мои два главных решения были: купить больше оперативной памяти или страницу в данных.

Самое близкое, что вы могли бы сделать, это использовать функцию mex для выделения разделяемой памяти, а затем разрешить последовательные вызовы функции mex, чтобы извлечь меньшие фрагменты памяти. Вы не хотели бы оборачивать разделяемую память как массив Matlab (потому что модель памяти Matlab не справилась бы с этим хорошо).

Я собирался предложить изучить memmap, но, видимо, это проблематично .

Иногда вы можете сначала запустить одну программу Matlab для предварительной обработки или разбить данные на более мелкие куски. Тогда каждый из процессов Matlab может работать со своим меньшим фрагментом.

Вот учебник по работе с большими наборами данных в Matlab.

1 голос
/ 18 мая 2009

Вероятно, нет, по крайней мере, не так, как вы обрабатываете данные как обычную переменную MATLAB.

Если на компьютере с Windows вы можете создать оболочку COM / ActiveX для доступа к вашим общим данным. MATLAB позволяет использовать COM-объекты с помощью функции actxserver. Но сомнительно, что вы могли бы получить доступ к данным «напрямую» через различные процессы. Между MATLAB и COM существует какой-то слой маршалинга, и данные преобразуются, по крайней мере, в соответствии с документацией Mathworks на , обмениваясь данными между MATLAB и COM . Если бы у меня абсолютно было для совместного использования структурированных данных между процессами с быстрым доступом на компьютере с Windows, я бы, вероятно, написал что-то на C ++ для использования общей памяти через Boost :: interprocess оберните доступ к нему в внутрипроцессном COM-сервере (DLL). Я делал это раньше, один раз. Как Boost :: interprocess делает его намного проще, так это боль.

Подход Java (поскольку MATLAB работает поверх Java) был бы гораздо более перспективным, но, насколько я знаю, нет достойных библиотек Java, обеспечивающих доступ к разделяемой памяти. Возможно, наиболее близким является использование файла с отображением в памяти через java.nio.MappedByteBuffer , но это действительно низкоуровневый файл. Тем не менее, если ваши данные представлены в относительно «квадратной» форме (например, большая двумерная, трехмерная или четырехмерная матрица данных однородного размера), это может работать нормально.

Вы можете попробовать использовать файлы HDF5, MATLAB имеет встроенную поддержку HDF5 , и это «относительно» быстро. Но по моему опыту, HDF5 не очень хорошо работает с параллелизмом. (По крайней мере, когда один процесс пишет, а другие читают. Если есть несколько читателей и нет пишущих, это работает просто отлично.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...