2009-05-16 22 views
6

¿Hay alguna forma de compartir memoria entre los procesos de MATLAB en la misma computadora?¿Cómo puedo compartir memoria entre procesos en MATLAB?

Estoy ejecutando varios procesos MATLAB en una computadora multi-core (con Windows, si es que importa). Todos usan los mismos datos de entrada gigantescos. Sería bueno tener solo una copia en memoria.

Editar: Desafortunadamente, cada proceso necesita acceso a toda la información de entrada gigantesca, por lo que no hay forma de dividir los datos y conquistar el problema.

+1

Mis datos pueden ser grandes, pero es estática, es decir, la función no se cambie. Sí. Leer un archivo podría funcionar. – AnnaR

Respuesta

6

Si los procesos sólo ha leído los datos, pero no modifican , entonces yo creo que puede colocar sus datos de entrada en un archivo grande y hacer que cada proceso abierto y leído de ese archivo. Cada proceso tendrá su propio indicador de posición de archivo que puede moverse a cualquier parte del archivo para leer los datos que necesita. Probé teniendo dos procesos de MATLAB leyendo simultáneamente de un archivo un millón o más por cada uno y todo parecía funcionar bien. Solo usé comandos de E/S de archivos básicos (enumerados a continuación). Parece que también puede hacer esto usando MEMMAPFILE, como Mr Fooz mencionado en su respuesta (y SCFrench en un comentario), suponiendo que tiene la versión R2008a o posterior de MATLAB.

Éstos son algunos de los archivos de E/S comandos que es probable que utilice para esto:

  • FOPEN: Cada proceso llamará FOPEN y devolver un identificador de archivo se utilizará en todas las llamadas posteriores. Puede abrir un archivo en cualquiera binario o texto modo:

    fid = fopen('data.dat','r'); % Binary mode 
    fid = fopen('data.txt','rt'); % Text mode 
    
  • FREAD: En modo binario, FREAD leerá los datos desde el archivo:

    A = fread(fid,20,'double'); % Reads 20 double-precision values 
    
  • FSCANF: En el texto modo, FSCANF leerá y formateará los datos del archivo:

    A = fscanf(fid,'%d',4); % Reads 4 integer values 
    
  • FGETL/FGETS: en modo texto, leerán líneas enteras del archivo.

  • FTELL: Esto le dirá el indicador de posición actual del fichero en bytes desde el comienzo del archivo:

    ftell(fid) 
    ans = 
        8 % The position indicator is 8 bytes from the file beginning 
    
  • FSEEK: Esto establecerá el indicador de posición del fichero a una posición deseada en el archivo:

    fseek(fid,0,-1); % Moves the position indicator to the file beginning 
    
  • FCLOSE: Cada proceso tendrá que cerrar su acceso al archivo (que es fácil de olvidar para hacer esto):

    fclose(fid); 
    

Esta solución es probable que requiera que el archivo de entrada tiene un formato bien estructurado que es fácil de recorrer (es decir, solo una matriz grande). Si tiene muchos campos de longitud variable, leer los datos desde la posición correcta en el archivo podría ser muy complicado.


Si los procesos tienen que modificar también los datos, esto podría ser aún más difícil. En general, no desea que una ubicación de archivo/memoria sea escrita simultáneamente por procesos múltiples, o escrita por un proceso mientras que otra está leyendo desde la misma ubicación, ya que puede resultar en un comportamiento no deseado. En tal caso, deberá limitar el acceso al archivo de modo que solo opere un proceso a la vez. Otros procesos tendrían que esperar hasta que termine el primero.Una versión de muestra de código que cada proceso tendría que funcionar en tal caso es:

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 

mecanismos de sincronización como estos ("locks") a veces pueden tener una alta sobrecarga que reduce la eficiencia paralelo general del código.

+0

¡Guau! Voy a probar esto. Esto posiblemente podría resolver mi problema. – AnnaR

4

EDITAR: Poner los datos en un archivo sin procesar y usar memmapfile (gracias SCFrench).

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

No, no hay una forma real de hacerlo.

Mis dos mejores soluciones han sido: comprar más RAM o página en los datos.

Lo más cercano que podría hacer sería usar una función mex para asignar memoria compartida, luego permitir llamadas sucesivas a la función mex para extraer porciones más pequeñas de la memoria. No querría envolver la memoria compartida como una matriz de Matlab (porque el modelo de memoria de Matlab no lo manejaría bien).

Iba a sugerir mirar en memmap, pero aparentemente es problematic.

A veces se puede ejecutar primero un programa de Matlab para preprocesar o dividir los datos en trozos más pequeños. Entonces, cada uno de los procesos de Matlab puede operar en su propio trozo más pequeño.

Aquí hay un tutorial sobre el tratamiento de grandes conjuntos de datos en Matlab.

+0

No era la respuesta que quería: deseaba un 'Sí, es posible, haz esto'. Pero muchas gracias por el enlace, lo voy a leer ahora mismo. – AnnaR

+0

He hurgado un poco más y tal vez éste lo hace: http://polaris.cs.uiuc.edu/matmarks/ –

+1

He publicado una actualización del hilo de noticias comp.soft-sys.matlab vinculado anteriormente al palabra "problemática". Resultó que esto era un error en las versiones anteriores de MATLAB, y se corrigió a partir de R2008a. – SCFrench

1

Probablemente no, al menos no en la forma en que trata los datos como una variable regular de MATLAB.

Si está en un equipo con Windows, puede crear un contenedor COM/ActiveX para acceder a sus datos compartidos. MATLAB permite el uso de objetos COM a través de la función actxserver. Pero es cuestionable si realmente podría acceder a los datos "directamente" a través de diferentes procesos. Existe algún tipo de capa de cálculo de referencias entre MATLAB y COM y los datos se convierten, al menos de acuerdo con los documentos de Mathworks en exchanging data between MATLAB and COM. Si tuviera absolutamente tenía para compartir datos estructurados entre procesos, con acceso rápido, en una máquina con Windows, probablemente escribiría algo en C++ para usar la memoria compartida a través de Boost::interprocess y ajustaré el acceso a ella en un servidor COM en proceso (DLL) He hecho esto antes, una vez. Tanto como Boost :: interprocess lo hace mucho más fácil, es un dolor.

El enfoque de Java (ya que MATLAB se ejecuta sobre Java) sería mucho más prometedor, pero hasta donde yo sé, no hay bibliotecas decentes de Java para proporcionar acceso a la memoria compartida. Lo más parecido es, probablemente, utilizar un archivo mapeado en memoria a través del java.nio.MappedByteBuffer, pero eso es realmente de bajo nivel. Aún así, si sus datos están en una forma relativamente "cuadrada" (por ejemplo, una gran matriz 2-D o 3-D o 4-D de datos de tamaño homogéneo), esto podría funcionar bien.

Puede intentar usar archivos HDF5, MATLAB tiene incorporado HDF5 support y es "relativamente" rápido. Pero desde mi experiencia, HDF5 no parece jugar muy bien con la concurrencia. (al menos no cuando un proceso está escribiendo y los otros son lectores. Si hay varios lectores y ningún escritor, funciona bien).)

5

Es posible que desee pago my presentación de intercambio de archivos Matlab "sharedmatrix" # 28572. Permite que exista una matriz de Matlab en la memoria compartida, siempre que esté utilizando algún sabor de Unix. Se podría entonces adjuntar la matriz compartida en un cuerpo de un parfor o spmd, es decir,

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

Desde X existe en la memoria compartida para el cuerpo de la spmd (o parfor) que no tiene tiempo de carga y no el tiempo de comunicación . Desde la perspectiva de Matlab, es una variable recién creada en el cuerpo spmd (o parfor).

Saludos,

Josh

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

Cuestiones relacionadas