Tamaño de pila predeterminado para pthreads

24

Según tengo entendido, el tamaño de pila predeterminado para un pthread en Linux es 16K. Estoy obteniendo resultados extraños en mi instalación de Ubuntu de 64 bits.

$ ulimit -s
8192

También:

pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &stacksize);
printf("Thread stack size = %d bytes \n", stacksize);

Prints
    Thread stack size = 8388608 bytes

Estoy bastante seguro de que el tamaño de la pila no es "8388608". ¿Qué podría estar mal?

Kamath
fuente
77
Creo 8388608 / 1024 = 8192.
Cuonglm
66
Estás pensando en pilas de kernel de 16k por hilo . Problema totalmente separado de la memoria de pila de espacio de usuario. las pilas de kernel son pequeñas porque no se pueden paginar o asignar de manera diferida, y deben ser páginas contiguas en la memoria física. elinux.org/Kernel_Small_Stacks . Tener un número extremadamente alto de subprocesos totales puede ser un problema para i386, donde el espacio de direcciones es limitado, especialmente con pilas de 8k por defecto para 32 bits.
Peter Cordes

Respuestas:

21
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);

El stacksizeatributo definirá el tamaño mínimo de pila (en bytes) asignado para la pila de hilos creados.

En su ejemplo, el tamaño de la pila se establece en 8388608 bytes que corresponde a 8 MB, según lo devuelto por el comando ulimit -s So that coincide.

De la pthread_create()descripción:

En Linux / x86-32 , el tamaño de pila predeterminado para un nuevo subproceso es de 2 megabytes . Bajo la implementación de subprocesos NPTL, si el límite de recursos blandos RLIMIT_STACK en el momento en que se inició el programa tiene un valor distinto de "ilimitado", determina el tamaño de pila predeterminado de los nuevos subprocesos. Usando pthread_attr_setstacksize (3), el atributo de tamaño de pila se puede establecer explícitamente en el argumento attr utilizado para crear un hilo, a fin de obtener un tamaño de pila diferente al predeterminado.

Por lo tanto, el tamaño de la pila de subprocesos se puede establecer mediante la función de configuración anterior o la ulimitpropiedad del sistema. Para los 16k a los que te refieres, no está claro en qué plataforma has visto eso y / o si se estableció algún límite del sistema para esto.

Vea la página pthread_create y aquí algunos ejemplos interesantes sobre esto.

fduff
fuente
47

En realidad, el tamaño de su pila virtual es 8388608 bytes (8 MB). Por supuesto, es natural concluir que esto no puede ser correcto, porque esa es una cantidad ridículamente grande de memoria para cada subproceso para su pila cuando el 99% de las veces un par de KB es probablemente todo lo que necesitan.

La buena noticia es que su hilo solo usa la cantidad de memoria física que realmente necesita. Este es uno de los poderes mágicos que obtiene su sistema operativo al usar la Unidad de administración de memoria de hardware (MMU) en su procesador. Esto es lo que pasa:

  1. El sistema operativo asigna 8 MB de memoria virtual para su pila configurando las tablas de páginas de MMU para su hilo. Esto requiere muy poca RAM para contener solo las entradas de la tabla de páginas.

  2. Cuando su hilo se ejecuta e intenta acceder a una dirección virtual en la pila que aún no tiene asignada una página física, la MMU activa una excepción de hardware llamada "fallo de página".

  3. El núcleo de la CPU responde a la excepción de falla de página cambiando a un modo de ejecución privilegiado (que tiene su propia pila) y llamando a la función del controlador de excepción de falla de página dentro del núcleo.

  4. El kernel asigna una página de RAM física a esa página de memoria virtual y vuelve al subproceso de espacio de usuario.

El hilo del espacio del usuario no ve nada de ese trabajo. Desde su punto de vista, solo usa la pila como si la memoria estuviera allí todo el tiempo. Mientras tanto, la pila crece automáticamente (o no) para satisfacer las necesidades del hilo.

La MMU es una parte clave del hardware de los sistemas informáticos actuales. En particular, es responsable de gran parte de la "magia" en el sistema, por lo que recomiendo aprender más sobre lo que hace la MMU y sobre la memoria virtual en general. Además, si su aplicación es sensible al rendimiento y maneja una cantidad significativa de datos, debe comprender cómo funciona el TLB (el caché de la tabla de páginas de MMU) y cómo puede reestructurar sus datos o sus algoritmos para maximizar su tasa de aciertos TLB.

jtchitty
fuente