2010-07-14 7 views
12

En C/C++ bajo Linux, necesito asignar un gran bloque de memoria (varios gigabytes), para almacenar datos en tiempo real desde un sensor conectado al puerto ethernet y transmitir datos a alrededor de 110MB/s. Me gustaría asignar la mayor cantidad de memoria posible, para maximizar la longitud de la secuencia de datos que puedo almacenar. Sin embargo, también necesito asegurarme de que no haya intercambio de disco, ya que la demora resultante y el ancho de banda limitado de acceso al disco hacen que el buffer (muy limitado) del sensor se desborde.Asignando el buffer más grande sin usar swap

¿Cuál es la mejor manera de determinar cuánta memoria asignar? ¿Estoy limitado a solo asignar un bloque un poco más pequeño que la memoria libre reportada, o puedo interactuar más directamente con el administrador de memoria virtual de Linux?

+0

Por puro interés, ¿qué sensor está utilizando? – Konrad

+0

Duplicado de http://stackoverflow.com/questions/2513505/ –

+0

@ Space_C0wb0y: no es realmente. – Hasturkun

Respuesta

9

Bueno, en Linux se puede utilizar mlock()/mlockall() para mantener un rango de direcciones de memoria física y evitar que sea intercambiado. El proceso que utiliza mlock necesita un par de privilegios para hacerlo, "man mlock" tiene los detalles. No estoy seguro del bloque mlock'able máximo (puede diferir de lo que parece ser "libre"), por lo que probablemente una búsqueda binaria podría ayudar (bloquear un rango, si eso falla, reducir el tamaño del área, etc.)

Por otro lado, 110 MB/s no es realmente un problema para una unidad de estado sólido. Un SSD de 60GB con velocidad de escritura de 280MB/s cuesta alrededor de $ 200 en la esquina. Simplemente copie los datos del sensor en un pequeño búfer de escritura y transmítalos al SSD.

0

Si malloc la cantidad necesaria de memoria y escribir en él a esa velocidad, que todavía tendrá un impacto en el rendimiento debido a todos los fallos de página (es decir, la cartografía de cada página de la memoria virtual a la memoria física, que también puede incluir intercambio de memoria de otros procesos).

Para evitar eso, podría memset el búfer completo asignado a 0 antes de comenzar a leer desde el sensor, de modo que toda la memoria virtual necesaria se asigne a la memoria física.

Si solo utiliza la memoria física disponible, no debe sufrir ningún intercambio. Si utiliza más, la memoria de otros procesos se intercambiará en el disco; si estos procesos están inactivos, no debería plantear ningún problema. Si están activos (es decir, utilizando su memoria de vez en cuando), se produciría algún intercambio, probablemente a un ritmo mucho menor que el ancho de banda de la unidad de disco duro. Cuanta más memoria utilice, más memoria de procesos activos se intercambiarán, y se producirán más actividades de HD; en este punto, la cantidad máxima de memoria que puede usar con un rendimiento decente es prácticamente el resultado de la prueba y error.

Al utilizar más de la memoria física disponible, definitivamente causará un intercambio a la velocidad de las escrituras de memoria, y no hay forma de evitar eso.

+2

No es necesario usar 'memset()' para engañar al sistema y asignarle memoria física. Use 'mlock()' para hacerlo explícitamente y asegúrese de que nunca se canjee. –

+0

Gracias por señalar esto. –

0

¿Cuál es la mejor manera de determinar cuánta memoria asignar?

Debido a la forma en que se utiliza la memoria virtual, la memoria del kernel no intercambiable, es casi imposible identificar a qué cantidad de memoria instalada se puede acceder mediante una aplicación.

Lo mejor que se me ocurre es permitir al usuario configurar cuánta memoria usar para el almacenamiento en búfer.

Estoy limitado a simplemente asignando un bloque ligeramente menor que el reportado memoria libre,

Informó memoria libre no es realmente "memoria física libre." Desafortunadamente.

o puedo interactuar más directamente con el administrador de memoria virtual de Linux?

Esto se puede hacer utilizando un controlador de dispositivo personalizado, asignando memoria directamente en el espacio del kernel y proporcionando acceso a ella a través del mmap(). Generalmente no recomendado, sin embargo funcionaría en casos especializados como el suyo.

Sin embargo, también necesito para asegurarse de que no habrá intercambio de discos

Al ritmo del desarrollo del núcleo Linux, el conocimiento se vuelve obsoleto muy rápido, por lo que tomar con pinzas lo que Estoy diciendo aquí. Usted puede tratar de jugar con lo siguiente: memoria compartida

  1. SysV. Por lo general, no se intercambia. Ver man shmget.

  2. tmpfs - sistema de archivos en memoria. La memoria estaba anclada a la memoria RAM al menos en los primeros núcleos 2.6 y, por lo tanto, no se podía intercambiar. Para usarlo como memoria, cree un archivo en tmpfs, write() algo en el archivo (para forzar que la memoria esté realmente asignada) y luego mmap() el archivo.

+0

Solo para los registros, * tmpfs * es, de hecho, intercambiable. Hay otra variante * rootfs * que nunca se intercambiará. Pero solo por eso debes ser muy cuidadoso con esto y no debes sobrecargarlo. –

0

Después de asignar la memoria, que podría

echo 0 > /proc/sys/vm/swappiness 

Para hacer el núcleo preferir reivindicación de la memoria de la memoria caché en lugar de cambiar.

Sólo mi $ 0,2

+1

La pregunta no es cómo evitar el intercambio, sino cómo determinar la cantidad de memoria que se puede asignar sin necesidad de cambiar. Y previene el intercambio de un búfer particular utilizando 'mlock()', no un hack de todo el sistema para el administrador de memoria. –

+0

Gracias, es bueno saberlo. :) – miedwar

3

Si el sistema de la computadora está dedicado a recibir datos de su sensor, simplemente puede deshabilitar el intercambio. A continuación, asigne el mayor búfer posible, dejando suficiente memoria en el sistema solo para las herramientas esenciales.

+0

Lamentablemente no es un sistema dedicado. Sin embargo, tiene mucha RAM para sus otros usos, por lo que deshabilitar el intercambio podría ser una opción. –

+0

Compruebe el uso de la memoria durante un tiempo. Es posible que veas que el intercambio casi nunca se utiliza a menos que alguna aplicación empiece a perder memoria como loca. He estado ejecutando sistemas de escritorio sin swap sin ningún problema. Pero para una solución más general use mlock (2) como aconsejaba Luther. Y no asigne todo como un buffer continuo. El administrador de memoria puede tener problemas para asignarlo (o reasignarlo). Utilice muchos búferes más pequeños vinculados en uno por alguna interfaz. De esta manera usted puede, por ejemplo, ajustar el tamaño del búfer en el tiempo de ejecución. –

+0

Thumbs up for "buffor" deletreo: P! – Cray

Cuestiones relacionadas