¿Los hilos usan memoria virtual o memoria real?

10

Intenté optimizar mi servidor Linux para manejar 10,000 subprocesos por proceso, mientras que solo hace 382 en este momento. Según este artículo, la siguiente fórmula se utiliza para encontrar el total de hilos posibles:

number of threads = total virtual memory / (stack size*1024*1024)

Esto significa que los hilos almacenan todos sus datos en la memoria virtual. Y que yo sepa, la memoria virtual es espacio de intercambio en una máquina Linux que se almacena en un disco duro que la RAM o el caché.

Entonces mi pregunta es si nuestros hilos usan un disco duro para almacenar para procesar / almacenar sus datos.

En caso afirmativo, ¿esto no afecta el rendimiento? ¿Podemos mejorar el rendimiento poniéndolos en RAM o caché? ¿Cómo?

Si no, ¿cómo funcionan exactamente los hilos?

Actualizar:

Según la respuesta inútil , la memoria virtual es un sistema que comprende aproximadamente:

  • memoria física (RAM)
  • cualquier intercambio que haya adjuntado
  • soporte de hardware para traducir direcciones virtuales a físicas y emitir fallas de página cuando una dirección virtual no está disponible en la memoria física
  • (kernel) soporte de software para: administrar las tablas de búsqueda utilizadas por ese hardware y manejar las fallas de la página al extraer las páginas del intercambio bajo demanda

Por lo tanto, todo lo que está en la memoria virtual está colectivamente en RAM (memoria real) y disco duro (archivos de intercambio). Y como James explica en su respuesta, Kernel toma la decisión de Ram vs HDD usando algoritmos como LRU.

dragosrsupercool
fuente
2
a menos que su servidor tenga 10.000 CPU / núcleos, está perdiendo el tiempo.
@JarrodRoberson: ¿Por qué es eso?
dragosrsupercool
3
10,000 hilos no es una buena manera de hacer que las cosas escalen, es una buena manera de hacer que un servidor se detenga, más de 1 hilo por CPU o Core solo hará que el contexto del servidor cambie y funcione más lento, no más rápido.
Específicamente, cuando dices "tratando de optimizar mi servidor Linux", ¿qué estás tratando de optimizar? Si se trata de rendimiento, es probable que un subproceso por CPU con multiplexación y E / S sin bloqueo sea mejor.
Inútil

Respuestas:

12

que yo sepa, la memoria virtual es espacio de intercambio en una máquina Linux

No, la memoria virtual es un sistema que comprende aproximadamente:

  • memoria física (RAM)
  • cualquier intercambio que haya adjuntado
  • soporte de hardware para traducir direcciones virtuales a físicas y emitir fallas de página cuando una dirección virtual no está disponible en la memoria física
  • (kernel) soporte de software para:
    • administrar las tablas de búsqueda utilizadas por ese hardware
    • manejar esas fallas de página sacando páginas del intercambio bajo demanda

Depende del núcleo asegurarse de que la memoria virtual que desea esté almacenada en caché en la RAM cuando lo desee, a menos que esté escribiendo su propia capa VM de espacio de usuario (como las bases de datos a menudo lo hacen, iiuc), simplemente no se preocupe.

Inútil
fuente
Ok, entonces mi suposición de memoria virtual estaba equivocada. De todos modos, una pregunta de seguimiento rápida. ¿Se vería afectado el rendimiento máximo de subprocesos cargados si SWAP Space es más que RAM?
dragosrsupercool
@dragosrsupercool: su espacio de intercambio siempre será más grande que la memoria física, de lo contrario, es necesario usar memoria virtual.
Bryan Oakley
1
@BryanOakley: Eso no es necesariamente cierto. Algunos sistemas operativos asignan una página de intercambio para cada página virtual asignada (es decir, el intercambio debe ser al menos tan grande como físico). Otros sistemas operativos asignan una página de intercambio solo cuando es necesario mover una página fuera de la memoria física (es decir, el intercambio puede ser menor que el físico). La ventaja de la primera es que si la asignación tiene éxito, el intercambio de esa memoria siempre es exitosa. La ventaja de este último es que no necesita asignar pesimista archivos de intercambio enormes para tener en cuenta situaciones relativamente raras.
mcmcc
1
@dragosrsupercool, el rendimiento no se verá afectado por la cantidad de RAM, el intercambio o la relación entre ellos a menos que tenga poca RAM y paginación real. sar puede informarle sobre la actividad de paginación iirc (marcado: sar -Ben Linux).
Inútil
@ Inútil: deseo aumentar el número de subprocesos hasta que utilice completamente la RAM y no comience a paginar.
dragosrsupercool
14

Si el hilo realmente se está ejecutando, la instrucción actual y cualquier variable que el hilo esté usando deben estar en la memoria física.

La mayoría de los programas (de hecho, casi todos) residen en la memoria virtual, y la mayoría de los programas usan memoria virtual para el almacenamiento de variables.

Direcciones virtuales organizadas en fragmentos llamados páginas (generalmente son bloques de 4096 u 8192 bytes).

En cualquier momento dado, cada bloque de memoria virtual se almacena en algún lugar de la memoria real o en el disco en el "espacio de intercambio" reservado para esto.

Su código de programa trata con direcciones virtuales, cuando se bifurca a una dirección virtual o solicita acceso al almacenamiento en una dirección virtual, el sistema (generalmente a nivel de hardware) localiza la ubicación actual de la solicitud de dirección y la asigna a su dirección virtual, si la dirección reside actualmente en el disco, la pagina en la memoria real y luego asigna la dirección.

Obviamente, cuando toda la memoria física está en uso si algo está paginado, entonces algo más debe ser paginado, por lo que el sistema busca la página "Menos utilizada recientemente" y la copia en el disco antes de copiar la página solicitada.

En los sistemas modernos hay varias optimizaciones y trucos asociados con el almacenamiento virtual.

  • Las direcciones se asignan "por proceso", por lo que, por ejemplo, todos los programas de C en un cuadro de Linux inician el proceso "principal" en la misma dirección.
  • Esto puede permitir que varios procesos de 32 bits ocupen y utilicen mucho más de 4 GB en una máquina, ya que una dirección virtual de 32 bits se puede asignar a una dirección real de 64 bits.
  • Cuando los procesos finalizan o la memoria está "libre", el sistema simplemente marca las páginas como libres, nunca se vuelven a copiar en el disco de intercambio.
  • De manera similar, cuando se solicita un nuevo bloque de almacenamiento, el sistema simplemente toma una página libre en la memoria real, no, se lleva a cabo el disco IO.
  • Las funciones de suspensión e hibernación obligan a copiar toda la memoria en el espacio de intercambio para que todos los procesos actuales y los contenidos actuales de la memoria puedan recrearse al despertar.
James Anderson
fuente
3
Parece que "todos los programas de C en un cuadro de Linux comienzan [principal] en la misma dirección" parece no tener en cuenta la aleatorización del diseño del espacio de direcciones. Eso se usa cada vez más hoy para frustrar varios esquemas de ataque aplastante de la pila. Buena respuesta de lo contrario, entonces +1.
un CVn
7

En primer lugar, necesita leer más en la memoria de la computadora , porque parece que le falta el conocimiento en ese campo.

Un hilo de ejecución es la unidad de procesamiento más pequeña que puede programar un sistema operativo. La implementación de hilos y procesos difiere de un sistema operativo a otro, pero en la mayoría de los casos, un hilo está contenido dentro de un proceso. Pueden existir múltiples subprocesos dentro del mismo proceso y compartir recursos como la memoria, mientras que diferentes procesos no comparten estos recursos.

Por lo tanto, los hilos utilizarán la memoria disponible, sea cual sea el tipo de memoria disponible. La cantidad de subprocesos que puede iniciar depende del tamaño de la memoria y de la cantidad de memoria necesaria por subproceso. Si el subproceso usa el montón (no solo la pila), entonces necesita más memoria y, en ese caso, puede iniciar menos subprocesos.

BЈовић
fuente
@VJonvic: +1 para la explicación básica del hilo.
dragosrsupercool
6

La respuesta simple a su pregunta es que usan memoria virtual. todo usa memoria virtual, excepto un puñado de procesos relacionados con el sistema operativo.

Por otro lado, cuando su hilo (o cualquier hilo, en cualquier proceso) realmente se está ejecutando, está usando memoria física. Las páginas de memoria asociadas con ese proceso se intercambian en la memoria física, que es donde el procesador hace su trabajo.

Bryan Oakley
fuente
3

La memoria virtual es tu RAM más tu espacio de intercambio. Virtual simplemente significa que la dirección que ve su programa es diferente de la dirección que ve el chip RAM. Si necesita acceder a la memoria en el intercambio, el sistema operativo la moverá primero a la RAM. Si no desea ningún intercambio, simplemente desactívelo. Si tiene suficiente RAM, realmente no la necesita.

Dicho esto, a menos que tenga un procesador de 10.000 núcleos, aumentar a 10.000 subprocesos no es realmente una "optimización". Una vez que tenga suficientes subprocesos para consumir todos los núcleos, más uno o dos de repuesto para cuando esos subprocesos estén bloqueados, agregar más subprocesos disminuye el rendimiento debido a la sobrecarga de conmutación y errores de caché. Es posible que aún desee utilizar más subprocesos si hace que la lógica de su programa sea más simple, pero estará cambiando el rendimiento.

Karl Bielefeldt
fuente
Sí, 10,000 es demasiado ya que mi servidor es una máquina de núcleo único de 32 bits. En realidad, los hilos no son cosa de CPU total. Son hilos de rastreo, por lo que a veces sería como esperar la respuesta del servidor. Mi objetivo es asegurarme de que la CPU esté totalmente ocupada pero no sobrecargada o subcargada. Pero aún no entiendo cómo puedo saber si la CPU está libre o totalmente ocupada. ¿Hay alguna herramienta o comando?
dragosrsupercool
Creo que puedes obtener esa información del topcomando.
Karl Bielefeldt
@KarlBieledeldt: sí, eso era exactamente lo que estaba buscando ... Una pregunta de seguimiento más: acabo de tener una idea para rastrear que si de alguna manera un hilo puede enviar una solicitud de URL mientras el otro hilo recibe la respuesta del servidor, entonces puedo mantener Uso de CPU alto sin usar demasiados hilos. ¿Es eso posible? ¿Le gusta enviar una solicitud de un hilo mientras recibe la respuesta en el otro hilo?
dragosrsupercool
2

optimizar mi servidor Linux para manejar 10,000 hilos por proceso

Como otros explicaron, esto generalmente está mal. Un subproceso es un recurso costoso , especialmente porque tiene su propia pila de llamadas (generalmente, un megabyte) y porque es una tarea programable por el núcleo. Los hilos son aún más costosos que los descriptores de archivos abiertos .

Lea los sistemas operativos: tres piezas fáciles (libro de texto de descarga gratuita).

Como regla general, no desea tener muchos subprocesos, y ciertamente no muchos subprocesos ejecutables. El número de subprocesos ejecutables generalmente debe ser como máximo el número de núcleos (o un pequeño múltiplo de eso), por lo que aproximadamente una docena como máximo. El número de subprocesos en un proceso podría ser ligeramente mayor. Entonces, a menos que tenga un servidor muy expansivo (con muchos zócalos y núcleos de procesador), no querrá tener más de una docena de subprocesos ejecutables y cien subprocesos (la mayoría de ellos están inactivos) en su proceso (en su escritorio) .

En Linux, los subprocesos y los procesos son muy similares (ya que ambos pueden ser creados por el clon (2) ) y ambos son tareas programadas por el núcleo. En realidad, el planificador del núcleo está programando tareas que pueden ser subprocesos dentro de un proceso de subprocesos múltiples, o el subproceso principal único de un proceso de subproceso único (en ese caso, nombrará "procesar" ese subproceso único) o subprocesos del núcleo. Probablemente no desee tener más de mil tareas programables en total en su sistema de escritorio.

En Linux, un proceso es simplemente un grupo de subprocesos que comparten el mismo espacio de direcciones virtuales (y comparten otras cosas, como la tabla de descriptores de archivos, etc.). Algunos procesos tienen solo un hilo.

Un espacio de direcciones virtuales se define por Wikipedia como

"el conjunto de rangos de direcciones virtuales que un sistema operativo pone a disposición de un proceso"

(pero vea también esta respuesta que explica que la terminología no es universal, y parte de la documentación de Microsoft usa una definición diferente e incompatible ).

En Linux, proc (5) es útil para comprender el espacio de direcciones virtuales de algunos procesos. Prueba ambos
cat /proc/self/mapsy cat /proc/$$/mapsen una terminal. Vea también esto , y pmap (1) y ps (1) y top (1) .

Todos los programas de espacio de usuario se ejecutan en algún proceso y usan memoria virtual, por lo que cada proceso tiene su propio espacio de dirección virtual. La RAM física es un recurso administrado por el kernel de Linux, y las aplicaciones no tienen acceso directo a la RAM (excepto por mmap (2) -ing /dev/mem, ver mem (4) ).

Entonces, un proceso no usa directamente RAM. Utiliza memoria virtual y tiene su propio espacio de direcciones virtuales. El kernel utiliza la paginación para administrar páginas físicas de RAM y proporcionar el espacio de direcciones virtuales y las abstracciones del proceso . En cualquier momento (incluso cuando su proceso está inactivo o cuando se está ejecutando), el núcleo podría extraer algunas páginas (por ejemplo, intercambiarlas en el disco). El núcleo está configurando la MMU (y manejando las excepciones de hardware de página perdidas en algún controlador de interrupciones , ya sea recuperando la página del disco o propagando una falla de segmentación al proceso, vea la señal (7) )

Podría tener hilos verdes por encima de los hilos del sistema (pero las bibliotecas de hilos verdes son difíciles de implementar y depurar). Mire las gorutinas utilizadas en Go para obtener un ejemplo elegante. Ver también setcontext (3) .

A veces, su sistema puede experimentar golpes . Esto sucede cuando la memoria virtual total (necesaria para todos los procesos) excede, en gran medida, la RAM física disponible. Entonces su computadora deja de responder. Lea sobre el tamaño del conjunto residente , la paginación de demanda , el conjunto de trabajo , el compromiso excesivo de memoria , ASLR .

Ver también -para Linux- fork (2) , clone (2) , mmap (2) , madvise (2) , posix_fadvise (2) , mlock (2) , execve (2) , credentials (7) , pthreads (7) , futex (7) , capacidades (7) .

Basile Starynkevitch
fuente