Dimensione dello stack predefinita per pthreads


24

A quanto ho capito, la dimensione dello stack predefinita per un pthread su Linux è 16 KB. Sto ottenendo strani risultati sulla mia installazione di Ubuntu a 64 bit.

$ ulimit -s
8192

Anche:

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

Prints
    Thread stack size = 8388608 bytes

Sono abbastanza sicuro che la dimensione dello stack non sia "8388608". Cosa potrebbe esserci di sbagliato?


7
Credo 8388608 / 1024 = 8192.
cuonglm,

6
Stai pensando a 16k per stack di kernel thread . Problema completamente separato dalla memoria dello stack dello spazio utente. gli stack del kernel sono minuscoli perché non possono essere paginati o allocati in modo pigro e devono essere pagine contigue nella memoria fisica. elinux.org/Kernel_Small_Stacks . Avere un numero estremamente elevato di thread totali può essere un problema per i386, dove lo spazio degli indirizzi è limitato, specialmente con stack da 8k di default per 32-bit.
Peter Cordes,

Risposte:


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

L' stacksizeattributo definisce la dimensione minima dello stack (in byte) allocata per lo stack di thread creato.

Nel tuo esempio, la dimensione dello stack è impostata su 8388608 byte, che corrisponde a 8 MB, come restituito dal comando ulimit -s So che corrisponde.

Dalla pthread_create()descrizione:

Su Linux / x86-32 , la dimensione dello stack predefinita per un nuovo thread è 2 megabyte . Nell'implementazione del thread NPTL, se il limite di risorse software RLIMIT_STACK al momento dell'avvio del programma ha un valore diverso da "illimitato", determina la dimensione dello stack predefinita dei nuovi thread. Utilizzando pthread_attr_setstacksize (3), l'attributo size dello stack può essere impostato esplicitamente nell'argomento attr utilizzato per creare un thread, al fine di ottenere una dimensione dello stack diversa da quella predefinita.

Quindi la dimensione dello stack del thread può essere impostata tramite la funzione set sopra o la ulimitproprietà di sistema. Per il 16k a cui ti riferisci, non è chiaro su quale piattaforma hai visto e / o se è stato impostato un limite di sistema per questo.

Vedi la pagina pthread_create e qui per alcuni esempi interessanti su questo.


47

In realtà, la dimensione dello stack virtuale è 8388608 byte (8 MB). Naturalmente, è naturale concludere che non può essere giusto, perché è una quantità ridicolmente grande di memoria per ogni thread da consumare per il suo stack quando il 99% delle volte un paio di KB è probabilmente tutto ciò di cui hanno bisogno.

La buona notizia è che il tuo thread utilizza solo la quantità di memoria fisica di cui ha effettivamente bisogno. Questo è uno dei poteri magici che il tuo sistema operativo ottiene dall'utilizzo dell'hardware Memory Management Unit (MMU) nel tuo processore. Ecco cosa succede:

  1. Il sistema operativo alloca 8 MB di memoria virtuale per il tuo stack impostando le tabelle delle pagine della MMU per il tuo thread. Ciò richiede pochissima RAM per contenere solo le voci della tabella delle pagine.

  2. Quando il thread viene eseguito e tenta di accedere a un indirizzo virtuale nello stack a cui non è stata ancora assegnata una pagina fisica, MMU genera un'eccezione hardware denominata "errore di pagina".

  3. Il core della CPU risponde all'eccezione di errore di pagina passando a una modalità di esecuzione privilegiata (che ha il proprio stack) e chiamando la funzione di gestione delle eccezioni di errore di pagina all'interno del kernel.

  4. Il kernel alloca una pagina di RAM fisica a quella pagina di memoria virtuale e ritorna al thread dello spazio utente.

Il thread dello spazio utente non vede nulla di tutto ciò. Dal suo punto di vista, usa semplicemente lo stack come se la memoria fosse lì da sempre. Nel frattempo, lo stack cresce automaticamente (o no) per soddisfare le esigenze del thread.

La MMU è una parte fondamentale dell'hardware dei sistemi informatici di oggi. In particolare, è responsabile di molta "magia" nel sistema, quindi consiglio vivamente di saperne di più su ciò che fa la MMU e sulla memoria virtuale in generale. Inoltre, se la tua applicazione è sensibile alle prestazioni e gestisce una notevole quantità di dati, dovresti capire come funziona il TLB (cache della tabella delle pagine della MMU) e come puoi ristrutturare i tuoi dati o i tuoi algoritmi per massimizzare il tuo hit rate TLB.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.