2009-05-16 15 views
6

Gibt es eine Möglichkeit, Speicher zwischen MATLAB-Prozessen auf demselben Computer gemeinsam zu nutzen?Wie kann ich Speicher zwischen Prozessen in MATLAB freigeben?

Ich führe mehrere MATLAB-Prozesse auf einem Multi-Core-Computer (unter Windows, wenn es darauf ankommt). Sie alle benutzen dieselben gigantischen Eingabedaten. Es wäre schön, nur eine einzige Kopie davon im Speicher zu haben.

Edit: Leider benötigt jeder Prozess Zugriff auf die gesamten riesigen Eingabedaten, so dass es keine Möglichkeit gibt, die Daten zu teilen und das Problem zu überwinden.

+1

Meine Daten groß sein kann, aber statisch, das heißt, wird die Funktion nicht geändert werden. Ja. Das Lesen einer Datei könnte tatsächlich funktionieren. – AnnaR

Antwort

6

Wenn die Prozesse immer nur lesen die Daten, aber nicht ändern es, dann glaube ich, Sie Ihre Eingabedaten in eine große Datei platzieren und haben jeden Prozess geöffnet und aus dieser Datei lesen. Jeder Prozess verfügt über einen eigenen Dateipositionsindikator, mit dem er sich überall in der Datei bewegen kann, um die benötigten Daten zu lesen. Ich testete, dass zwei MATLAB-Prozesse gleichzeitig eine Million Mal aus einer Datei lesen und alles schien gut zu funktionieren. Ich habe nur grundlegende Datei-E/A-Befehle verwendet (siehe unten). Es scheint, dass Sie dies auch mit MEMMAPFILE, wie Mr Fooz in seiner Antwort erwähnt (und SCFrench in einem Kommentar) tun können, vorausgesetzt, Sie haben MATLAB Version R2008a oder neuer.

Hier sind einige der Datei-I/O-Befehle, die Sie wahrscheinlich für diese verwenden:

  • FOPEN: Jeder Prozess wird FOPEN anrufen und eine Dateikennung zurückgeben in allen nachfolgenden Anrufe verwenden. Sie können in eine Datei öffnen, entweder binäre oder Text Modus:

    fid = fopen('data.dat','r'); % Binary mode 
    fid = fopen('data.txt','rt'); % Text mode 
    
  • FREAD: Im Binärmodus FREAD werden die Daten aus der Datei lesen:

    A = fread(fid,20,'double'); % Reads 20 double-precision values 
    
  • FSCANF: Im Text Modus wird FSCANF Daten aus der Datei lesen und formatieren:

  • FGETL/FGETS: Im Textmodus lesen diese ganze Zeilen aus der Datei.

  • FTELL: Dies wird Ihnen sagen, die aktuelle Anzeige Dateiposition in Bytes vom Anfang der Datei:

    ftell(fid) 
    ans = 
        8 % The position indicator is 8 bytes from the file beginning 
    
  • FSEEK: Diese Datei Positionsanzeiger in eine gewünschte Position in der Datei gesetzt werden:

    fseek(fid,0,-1); % Moves the position indicator to the file beginning 
    
  • FCLOSE: Jeder Prozess wird der Zugriff auf die Datei schließen (es ist einfach zu vergessen, dies zu tun):

    fclose(fid); 
    

Diese Lösung, die die Eingabedatei ein gut strukturiertes Format hat wahrscheinlich erfordern, die leicht zu durchlaufen ist (d nur eine große Matrix). Wenn es viele Felder variabler Länge hat, kann das Lesen von Daten von der richtigen Position in der Datei sehr schwierig werden.


Wenn die Prozesse müssen auch die Daten ändern, könnte dies noch schwieriger bekommen. Im Allgemeinen möchten Sie nicht, dass eine Datei/ein Speicherort gleichzeitig von mehreren Prozessen beschrieben oder von einem Prozess geschrieben wird, während ein anderer von demselben Speicherort liest, da unerwünschtes Verhalten die Folge sein kann. In einem solchen Fall müssten Sie den Zugriff auf die Datei so beschränken, dass jeweils nur ein Prozess ausgeführt wird. Andere Prozesse müssten warten, bis die erste fertig ist.Eine Probe-Version des Codes, die jeder Prozeß haben würde in einem solchen Fall ausgeführt werden soll:

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 

Synchronisationsmechanismen wie diese („locks“) kann manchmal eine hohe Overhead, der den Gesamt parallel Effizienz des Codes reduziert.

+0

Wow! Ich werde es versuchen. Dies könnte möglicherweise mein Problem lösen. – AnnaR

4

EDIT: Legen Sie die Daten in eine Raw-Datei und verwenden Sie memmapfile (Dank SCFrench).

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

Nein, es gibt keinen wirklichen Weg es zu tun.

Meine zwei besten Lösungen wurden: Kaufen Sie mehr RAM oder Seite in den Daten.

Die nächste Sache, die Sie tun könnten, wäre, eine mex-Funktion zu verwenden, um gemeinsam genutzten Speicher zuzuweisen, und dann aufeinanderfolgende Aufrufe an die mex-Funktion zu erlauben, kleinere Schichten des Speichers herauszuziehen. Sie möchten den geteilten Speicher nicht als Matlab-Array verwenden (weil das Speichermodell von Matlab dies nicht gut beherrscht).

Ich würde vorschlagen, in Memmap suchen, aber anscheinend ist es problematic.

Manchmal können Sie zuerst ein Matlab-Programm ausführen, um die Daten in kleinere Abschnitte vorzureichen oder aufzuteilen. Dann kann jeder der Matlab-Prozesse auf seinem eigenen kleineren Teilstück arbeiten.

Hier ist ein tutorial zum Umgang mit großen Datensätzen in Matlab.

+0

Nicht die Antwort, die ich wollte - ich wünschte mir ein "Ja, es ist möglich, mach das". Aber vielen Dank für den Link, ich werde es jetzt lesen. – AnnaR

+0

Ich habe ein wenig mehr herumgestochert und vielleicht tut es das hier: http://polaris.cs.uiuc.edu/matmarks/ –

+1

Ich habe ein Update auf den oben verlinkten comp.soft-sys.matlab News-Thread gepostet Wort "problematisch". Es stellte sich heraus, dass dies ein Fehler in älteren Versionen von MATLAB war und ab R2008a behoben wurde. – SCFrench

1

Wahrscheinlich nicht, zumindest nicht in der Art, wie Sie die Daten wie eine normale MATLAB-Variable behandeln.

Wenn Sie auf einem Windows-Computer einen COM/ActiveX-Wrapper für den Zugriff auf Ihre freigegebenen Daten erstellen können. MATLAB ermöglicht die Verwendung von COM-Objekten über die actxserver-Funktion. Es ist jedoch fraglich, ob Sie tatsächlich über verschiedene Prozesse "direkt" auf die Daten zugreifen könnten. Es gibt eine Art Marshalling-Schicht zwischen MATLAB und COM, und Daten werden konvertiert, zumindest gemäß den Mathworks-Dokumenten unter exchanging data between MATLAB and COM. Wenn ich absolut hatte, um strukturierte Daten zwischen Prozessen mit schnellem Zugriff auf einer Windows-Maschine zu teilen, würde ich wahrscheinlich etwas in C++ schreiben, um gemeinsamen Speicher über Boost::interprocess zu verwenden und den Zugriff darauf in einem In-Prozess-COM-Server (DLL). Ich habe das schon einmal gemacht. So viel wie Boost :: interprocess es viel einfacher macht, ist es ein Schmerz.

Der Java-Ansatz (da MATLAB auf Java läuft) wäre viel vielversprechender, aber soweit ich weiß, gibt es keine anständigen Java-Bibliotheken, die Zugriff auf Shared Memory bieten. Die nächste Sache ist wahrscheinlich die Verwendung einer Memory-Mapped-Datei über , aber das ist wirklich Low-Level. Wenn Ihre Daten jedoch in einer relativ "quadratischen" Form vorliegen (z. B. eine große 2-D- oder 3-D- oder 4-D-Matrix von Daten in homogener Größe), könnte dies OK sein.

Sie könnten versuchen, HDF5-Dateien zu verwenden, MATLAB hat HDF5 support eingebaut und es ist "relativ" schnell. Aber aus meiner Erfahrung scheint HDF5 nicht sehr gut mit Nebenläufigkeit zu spielen. (Zumindest nicht wenn ein Prozess schreibt und die anderen sind Leser. Wenn es mehrere Leser und keine Schreiber gibt, funktioniert es gut.

)
5

Sie können meine Matlab Datei-Austausch-Einreichung "sharedmatrix" # 28572 überprüfen. Es ermöglicht die Existenz einer Matlab-Matrix im Shared Memory, vorausgesetzt, Sie verwenden eine Variante von Unix. Man könnte dann die gemeinsame Matrix in einem Körper eines parfor oder SPMD befestigen, dh

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

Da X für den Körper des SPMD im gemeinsamen Speicher vorhanden ist (oder parfor) es hat keine Ladezeit und keine Kommunikationszeit . Aus der Perspektive von Matlab ist dies eine neu erstellte Variable im spmd (oder parfor) -Körper.

Cheers,

Josh

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

Verwandte Themen