2009-05-16 13 views
6

C'è un modo per condividere la memoria tra i processi MATLAB sullo stesso computer?Come posso condividere la memoria tra i processi in MATLAB?

Sto eseguendo diversi processi MATLAB su un computer multi-core (con Windows in esecuzione, se è importante). Tutti usano gli stessi giganteschi dati di input. Sarebbe bello avere una sola copia di esso in memoria.

Modifica: Sfortunatamente ogni processo richiede l'accesso a tutti i giganteschi dati di input, quindi non c'è modo di dividere i dati e conquistare il problema.

+1

miei dati personali possono essere grandi, ma è statico, cioè, la funzione non cambiarlo. Si. La lettura di un file potrebbe effettivamente funzionare. – AnnaR

risposta

6

Se i processi sempre e solo leggere i dati, ma non modificano, allora credo che è possibile inserire i dati di ingresso in un unico file di grandi dimensioni e di avere ogni processo aperto e leggere da quel file. Ogni processo avrà il proprio indicatore di posizione del file che può spostarsi ovunque nel file per leggere i dati di cui ha bisogno. Ho testato due processi MATLAB leggendo simultaneamente da un file circa un milione di volte ciascuno e tutto sembrava funzionare correttamente. Ho usato solo i comandi di I/O di file di base (elencati sotto). Sembra si potrebbe anche farlo usando MEMMAPFILE, come Mr Fooz menzionato nella sua risposta (e SCFrench in un commento), a patto di avere la versione di MATLAB R2008a o più recente.

Ecco alcuni dei file I/O comanda che si dovrà probabilmente usare per questo:

  • FOPEN: Ogni processo chiamerà FOPEN e restituire un identificatore di file userà in tutte le chiamate successive. È possibile aprire un file in entrambe le binario o testo modalità:

    fid = fopen('data.dat','r'); % Binary mode 
    fid = fopen('data.txt','rt'); % Text mode 
    
  • FREAD: In modalità binaria, FREAD leggerà i dati dal file:

    A = fread(fid,20,'double'); % Reads 20 double-precision values 
    
  • FSCANF: nel testo modalità, FSCANF leggerà e formatterà i dati dal file:

    A = fscanf(fid,'%d',4); % Reads 4 integer values 
    
  • FGETL/FGETS: In modalità testo, questi leggeranno intere righe dal file.

  • FTELL: Questo vi dirà l'indicatore di posizione del file corrente in byte dall'inizio del file:

    ftell(fid) 
    ans = 
        8 % The position indicator is 8 bytes from the file beginning 
    
  • FSEEK: Questo imposterà l'indicatore di posizione del file nella posizione desiderata nel file:

    fseek(fid,0,-1); % Moves the position indicator to the file beginning 
    
  • FCLOSE: Ogni processo dovrà chiudere il suo accesso al file (è facile dimenticare di fare questo):

    fclose(fid); 
    

Questa soluzione sarà probabilmente richiederà che il file di input ha un formato ben strutturato che è facile da attraversare (vale a dire solo una grande matrice). Se ha molti campi di lunghezza variabile, leggere i dati dalla posizione corretta nel file potrebbe diventare molto complicato.


Se i processi devono anche modificare i dati, questo potrebbe diventare ancora più difficile. In generale, non si desidera che un file/posizione di memoria venga scritto contemporaneamente da più processi o scritto da un processo mentre un altro sta leggendo dalla stessa posizione, poiché può verificarsi un comportamento indesiderato. In tal caso, si dovrebbe limitare l'accesso al file in modo tale che solo un processo alla volta funzioni su di esso. Altri processi dovrebbero aspettare fino a quando il primo è fatto.Una versione di esempio di codice che ogni processo dovrebbe funzionare in questo caso è:

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 

meccanismi di sincronizzazione come questi ("locks") possono talvolta avere un elevato sovraccarico che riduce l'efficienza parallelo complessiva del codice.

+0

Wow! Ci proverò. Questo potrebbe risolvere il mio problema. – AnnaR

4

MODIFICA: Inserire i dati in un file raw e utilizzare memmapfile (grazie SCFrench).

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

No, non esiste un modo reale di farlo.

Le mie due migliori soluzioni sono state: acquistare più RAM o una pagina nei dati.

La cosa più vicina che si potrebbe fare sarebbe utilizzare una funzione di messaggistica per allocare la memoria condivisa, quindi consentire chiamate successive alla funzione di messaggistica per estrarre sezioni più piccole della memoria. Non vorrai avvolgere la memoria condivisa come un array Matlab (perché il modello di memoria di Matlab non lo gestirà bene).

Stavo per suggerire di guardare in memmap, ma a quanto pare è problematic.

A volte è possibile eseguire prima un programma Matlab per pre-elaborare o suddividere i dati in blocchi più piccoli. Quindi ciascuno dei processi Matlab può operare su un blocco più piccolo.

Ecco uno tutorial relativo alla gestione di set di dati di grandi dimensioni in Matlab.

+0

Non è la risposta che volevo - volevo un "Sì è possibile, fai questo". Ma grazie mille per il link, ho intenzione di leggerlo proprio ora. – AnnaR

+0

Ho fatto un po 'più di spiccioli e forse questo lo fa: http://polaris.cs.uiuc.edu/matmarks/ –

+1

Ho postato un aggiornamento al thread di notizie comp.soft-sys.matlab collegato sopra al parola "problematico". Si è scoperto che si trattava di un bug nelle versioni precedenti di MATLAB ed è stato risolto a partire da R2008a. – SCFrench

1

Probabilmente no, almeno non nel modo in cui si trattano i dati come una variabile MATLAB regolare.

Se su un computer Windows, è possibile creare un wrapper COM/ActiveX per accedere ai dati condivisi. MATLAB consente l'uso di oggetti COM tramite la funzione actxserver. Ma è discutibile se si possa effettivamente accedere ai dati "direttamente" attraverso diversi processi. Esiste una sorta di livello di marshalling tra MATLAB e COM e i dati vengono convertiti, almeno secondo i documenti di Mathworks su exchanging data between MATLAB and COM. Se ho assolutamente avere per condividere i dati strutturati tra processi, con accesso rapido, su una macchina Windows, probabilmente scriverei qualcosa in C++ per usare la memoria condivisa tramite Boost::interprocess e racchiudere l'accesso ad esso in un server COM in-process (DLL). L'ho già fatto prima, una volta. Per quanto Boost :: interprocess lo rende molto più semplice, è un dolore.

L'approccio Java (dal momento che MATLAB gira su Java) sarebbe molto più promettente, ma per quanto ne so, non ci sono librerie Java decenti per fornire accesso alla memoria condivisa. La cosa più vicina è probabilmente quella di utilizzare un file mappato in memoria tramite java.nio.MappedByteBuffer, ma questo è davvero di basso livello. Tuttavia, se i vostri dati sono in una forma relativamente "quadrata" (ad esempio una grande matrice 2D o 3D o D-D di dati di dimensioni omogenee), ciò potrebbe funzionare correttamente.

Si potrebbe provare a utilizzare i file HDF5, MATLAB ha incorporato HDF5 support ed è "relativamente" veloce. Ma dalla mia esperienza, HDF5 non sembra giocare molto bene con la concorrenza. (almeno non quando un processo sta scrivendo e gli altri sono lettori. Se ci sono più lettori e senza scrittori, funziona perfettamente.)

5

Si consiglia di eseguire il checkout del mio invio di scambio di file Matlab "sharedmatrix" # 28572. Consente a una matrice Matlab di esistere nella memoria condivisa, a condizione che si stia utilizzando un po 'di sapore di Unix. Si potrebbe allora attaccare la matrice comune in un corpo di un parfor o SPMD, cioè,

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

Poiché X è presente nella memoria condivisa per il corpo del SPMD (o parfor) non ha tempo di caricamento e nessun tempo di comunicazione . Dal punto di vista di Matlab è una variabile appena creata nel corpo spmd (o parfor).

Cheers,

Josh

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

Problemi correlati