Pregunta

Mi problema es:

Tengo un script en perl que usa mucha memoria (comportamiento esperado debido al almacenamiento en caché). Pero, me di cuenta de que cuanto más hago el almacenamiento en caché, más lento se vuelve y el proceso pasa la mayor parte del tiempo en el modo de suspensión.

Pensé que la asignación previa de memoria al proceso podría acelerar el rendimiento.

¿Alguien tiene alguna idea aquí?

Actualizar :

Creo que no estoy siendo muy claro aquí. Pondré la pregunta de manera más clara:

No estoy buscando las formas de asignación previa dentro del script perl. No creo que eso me ayude mucho aquí. Lo que me interesa es una forma de decirle al sistema operativo que asigne X cantidad de memoria para mi script perl para que no tenga que competir con otros procesos que vienen más adelante.

Supongamos que no puedo salir con el uso de la memoria. Aunque, estoy explorando formas de reducir eso también, pero no espero mucha mejora allí. Para su información, estoy trabajando en una máquina solaris 10.

¿Fue útil?

Solución

Lo que he recopilado de tu publicación y comentarios es esto:

  • Su programa se vuelve lento cuando aumenta el uso de la memoria
  • Tu programa cada vez pasa más tiempo durmiendo, no computando.

Eplanación más probable: dormir significa esperar a que un recurso esté disponible. En este caso el recurso más probable es la memoria. Utilice el comando vmstat 1 para verificar. Echa un vistazo a la columna sr. Si va más allá de ~ 150, el sistema está desesperado por liberar páginas para satisfacer la demanda. Esto se acompaña de una alta actividad en las columnas pi, po y fr.

Si este es el caso, sus mejores opciones son:

  • Actualice la memoria del sistema para satisfacer la demanda
  • Reduzca el uso de memoria a un nivel apropiado para el sistema en cuestión.

La memoria de asignación previa no ayudará. En cualquier caso, la demanda de memoria excederá la memoria principal disponible en algún momento. El núcleo tendrá que decidir qué páginas deben estar en la memoria ahora y qué páginas se pueden borrar y reutilizar para las páginas que se necesitan con mayor urgencia. Si todas las páginas que se necesitan con regularidad (el conjunto de trabajo) exceden el tamaño de la memoria principal, el sistema está moviendo constantemente las páginas desde y hacia el almacenamiento secundario (intercambio). Luego se dice que el sistema está latiendo y no pasa mucho tiempo haciendo un trabajo útil. No hay nada que puedas hacer al respecto, agregar memoria o usar menos.

Otros consejos

De un comentario:

  

Las limitaciones de la memoria no son muy graves, pero la huella de la memoria aumenta fácilmente a GB y cuando tenemos procesos que compiten con la memoria, se vuelve muy lento. Quiero reservar algo de memoria del sistema operativo para que la paliza sea mínima incluso cuando hay muchos otros procesos. Jagmal

Tomemos una táctica diferente entonces. El problema no es realmente con su script de Perl en particular. En su lugar, todos los procesos en la máquina consumen demasiada memoria para que la máquina los maneje según lo configurado.

Puedes " reservar " Memoria, pero eso no evitará que se golpeen. De hecho, podría empeorar el problema porque el sistema operativo no sabrá si está usando la memoria o simplemente guardándola para más tarde.

Sospecho que estás sufriendo la tragedia de los comunes . ¿Tengo razón que muchos otros usuarios están en la máquina en cuestión? Si es así, esto es más un problema social que un problema técnico. Lo que necesita es que alguien (probablemente el administrador del sistema) intervenga y coordine todos los procesos en la máquina. Deben encontrar la memoria más extravagante y trabajar con sus programadores para reducir el costo de los recursos del sistema. Además, deberían organizar la programación de procesos para que la asignación de recursos sea eficiente. Finalmente, es posible que necesiten obtener más o un hardware mejorado para manejar la carga esperada del sistema.

Algunas preguntas que podrías hacerte:

  • ¿Son mis estructuras de datos realmente útiles para la tarea en cuestión?
  • ¿Realmente tengo que cachear tanto?
  • ¿Puedo tirar los datos en caché después de algún tiempo?
my @array;
$#array = 1_000_000; # pre-extend array to one million elements,
                     # http://perldoc.perl.org/perldata.html#Scalar-values

my %hash;
keys(%hash) = 8192; # pre-allocate hash buckets 
                    # (same documentation section)

Al no estar familiarizado con su código, aventuraré algunas especulaciones descabelladas aquí [sonrisa] de que estas técnicas no ofrecerán nuevas y excelentes eficiencias a su script, pero que la asignación previa podría ayudar un poco.

¡Buena suerte!

- Douglas Hunter

Hace poco redescubrí un excelente artículo de Randal L. Schwartz que incluye preasignación una matriz. Suponiendo que este es su problema, puede realizar una prueba de preasignación con una variación en ese código. Pero asegúrese de probar el resultado.

La razón por la que el script se vuelve más lento con más almacenamiento en caché puede ser thrashing . Presumiblemente, la razón para el almacenamiento en caché en primer lugar es aumentar el rendimiento. Así que una respuesta rápida es: reducir el almacenamiento en caché.

Ahora puede haber formas de modificar su esquema de almacenamiento en caché para que use menos memoria principal y evite las palizas. Por ejemplo, puede encontrar que el almacenamiento en caché en un archivo o base de datos en lugar de en la memoria puede mejorar el rendimiento. Descubrí que el sistema de archivos y el almacenamiento en caché de la base de datos pueden ser más eficientes que el almacenamiento en caché de la aplicación y pueden compartirse entre varias instancias.

Otra idea podría ser alterar su algoritmo para reducir el uso de memoria en otras áreas. Por ejemplo, en lugar de extraer un archivo completo en la memoria, los programas Perl tienden a funcionar mejor leyendo línea por línea.

Finalmente, ¿has explorado el módulo Memoize ? Puede que no sea de aplicación inmediata, pero podría ser una fuente de ideas.

Todavía no pude encontrar una manera de hacer esto.

Pero, descubrí que (vea this para más detalles)

  

Memoria asignada a los léxicos (es decir,   mis () variables) no pueden ser reclamadas o   Reutilizados incluso si salen fuera de alcance.   Se reserva en caso de las variables.   volver en el alcance Memoria asignada   Las variables globales pueden ser reutilizadas.   (dentro de su programa) usando   undef () ing y / o delete ().

Por lo tanto, creo que una posibilidad aquí podría ser comprobar si puedo reducir la impresión total en memoria de las variables léxicas en un momento dado.

Parece que está buscando limit o ulimit . Pero sospecho que causará que falle un script que supere el límite, lo que probablemente no sea lo que quieres.

Una mejor idea podría ser compartir datos en caché entre procesos. Poner los datos en una base de datos o en un archivo funciona bien en mi experiencia.

Odio decirlo, pero si sus limitaciones de memoria son tan graves, es probable que Perl no sea el idioma adecuado para esta aplicación. C sería una mejor opción, pensaría.

Una cosa que podrías hacer es usar las zonas solaris (contenedores).
Podría poner su proceso en una zona y asignarle recursos como RAM y CPU.
Aquí hay dos enlaces a algunos tutoriales:

  1. Solaris Containers How To Guide
  2. Control de recursos de zona en el SO Solaris 10 08/07

Si bien no es una asignación previa como solicitó, es posible que también desee ver las grandes opciones de tamaño de página, de modo que cuando Perl tenga que pedirle al sistema operativo más memoria para su programa, la obtenga. trozos más grandes.

Para obtener más información sobre el Esta diferencia hace y cómo hacerlo.

Mire http://metacpan.org/pod/Devel::Size

También puedes incluir una función c para hacer lo anterior.

Por lo que sé, no puede asignar memoria directamente desde Perl. Puede solucionar esto escribiendo un módulo XS o usando una función C en línea como mencioné.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top