2010-11-11 3 views
5

Sto scrivendo un codice che genera alcuni thread (circa 512 al momento, ma potrebbe aumentare in futuro). Ciascuno dei thread esegue solo una piccola quantità di operazioni, quindi voglio che il sovraccarico che i thread si posizionano sul sistema sia mantenuto al minimo.Dimensioni dello stack di thread sicuro?

Sto impostando la dimensione dello stack utilizzando pthread_attr_setstacksize() e posso ottenere la dimensione minima dello stack consentita da PTHREAD_STACK_MIN. Ma la mia domanda è: È sicuro usare PTHREAD_STACK_MIN per le dimensioni dello stack di thread? Come faccio a calcolare la quantità di stack di cui ho bisogno? Ci sono delle spese generali nascoste che dovrò aggiungere al mio calcolo?

Inoltre, esistono altre tecniche che posso utilizzare per ridurre il carico dei thread sul sistema?

risposta

4

Ridurre la dimensione dello stack di thread non ridurrà il sovraccarico (non in termini di CPU, utilizzo della memoria o prestazioni). Il tuo unico limite a questo riguardo è lo spazio di indirizzo virtuale disponibile totale per i thread sulla tua piattaforma.

Vorrei utilizzare la dimensione di stack predefinita fino a quando una piattaforma presenta problemi in caso contrario (se dovesse accadere del tutto). Quindi ridurre al minimo l'utilizzo dello stack se e quando si presentano problemi. Tuttavia, ciò porterà a problemi di prestazioni reali, poiché è necessario raggiungere l'heap o devise thread-dependent allocation altrove.

spese nascoste possono includere:

  • Assegnazione di array di grandi dimensioni in pila, come da VLA, alloca() o semplicemente staticamente dimensioni array automatici.
  • Codice che non si controlla o non era a conoscenza delle conseguenze dell'utilizzo di modelli, classi di produzione ecc. Tuttavia, dato che non si è specificato C++, è meno probabile che si tratti di un problema.
  • Codice importato dalle intestazioni delle librerie, ecc. Queste possono cambiare tra le versioni e alterare in modo significativo il loro stack, o persino l'utilizzo del thread.
  • Ricorsione. Ciò si verifica anche a causa dei punti precedenti, considerare cose come boost::bind, modelli variadic, macro pazzesche e quindi solo ricorsione generale utilizzando buffer o oggetti di grandi dimensioni nello stack.

È inoltre possibile impostare le dimensioni dello stack, manipolare le priorità del filo e sospenderlo e riprenderlo secondo necessità, il che aiuterà in modo significativo lo scheduler e la reattività del sistema. I pthread consentono di impostare l'ambito della contesa; LWP e nella pianificazione dell'ambito variano notevolmente nelle loro caratteristiche di prestazione.

Ecco alcuni link utili:

+0

Grazie Matt. Penso che questo sia il più vicino alla mia risposta. Speravo che qualcuno dicesse "aggiungi la sizeof() di tutte le variabili locali, aggiungi 42 byte per l'overhead del thread e poi aggiungi il 10% per buona fortuna", ma sembra che ci siano potenzialmente molti più fattori in gioco. Grazie per i suggerimenti su priorità e sospensione. –

+2

@ ltn100: no, è più come "testare accuratamente il codice con una dimensione dello stack specificata, in un contesto di debug che rileverà l'overflow, quindi aggiungere il 10% per la buona fortuna". –

+2

@ ltn100: Se riesci a trovare uno strumento di debug che misura effettivamente l'utilizzo di stack di high water sulla tua piattaforma, va bene, ma le piattaforme in cui devi effettivamente farlo (perché lo stack è RAM fisica in primo piano) non sono necessariamente quelli con i migliori strumenti di debug. E devi essere * veramente * approfondito con i test. Qualsiasi piccola cosa, incluse le modifiche alle librerie alle quali si collega dinamicamente, o le variabili d'ambiente che guardano, o (letteralmente) il giorno della settimana, potrebbe aumentare il tuo high-mark. Evita i VLA, evita qualsiasi ricorsione dipendente dai dati di input. –

7

Non dovresti creare da nessuna parte vicino a molti thread e sicuramente non dovresti creare una nuova discussione per eseguire una piccola quantità di operazioni. Dovresti creare un nuovo thread se e solo se i thread esistenti sono completamente saturati E ci sono più cure fisiche o logiche disponibili per lavorare. Ciò pone un limite irrisorio su una ragionevole applicazione corrente a circa 10 thread o giù di lì, anche se si correva su un hexacore avresti bisogno solo di circa 12 al massimo. Un tale design è molto imperfetto, userà un'enorme quantità di memoria di processo e non migliorerà davvero le prestazioni.

Per quanto riguarda la dimensione dello stack, non è possibile calcolare realmente quanto è necessario per un thread arbitrario, poiché dipende totalmente dall'esecuzione del codice. Tuttavia, in Visual Studio, la dimensione dello stack tipica è di alcuni megabyte. Dovresti pubblicare l'intero codice E lo smontaggio risultante eseguito dal thread per sapere quante dimensioni dello stack utilizzare. Basta attaccarlo a un paio di megabyte.

+1

+1: ma si consiglia più thread di core se le discussioni che sono regolarmente IO-bound ... –

+0

@ Oli, ma non il 50x come molti. –

+4

@C. Ross: dipende da come sono vincolati I/O. OK, quindi ci sono altri modi di costruire un sistema I/O asincrono che è più efficiente nelle risorse (e forse meno efficiente nel mio tempo, a seconda di quanto sono bravo con le code di eventi, 'select', ecc), ma se i miei thread passeranno il 99,8% del loro tempo in attesa di I/O di rete, quindi vorrei 500 thread. A volte la RAM è più economica dei programmatori, a volte non lo è ;-) –

5

La dimensione necessaria di stack frame dipendono dal compilatore si utilizza, in fondo si potrebbe provare a indovinare le dimensioni delle variabili auto, parametri e alcuni overhead per indirizzo di ritorno, salvando i registri ecc

Si dovrebbe considerare se sarebbe un'alternativa usare uno Thread Pool. Poiché la creazione di un thread non è gratuita.

+1

Sono scettico sul fatto che i pool di thread abbiano un vantaggio significativo sulle implementazioni moderne. Nessuno usa più 'LinuxThreads' e hack come quello. Hai un riferimento aggiornato sul costo relativo della creazione di thread? –

+1

Infatti. La creazione di thread varia in termini di costi, ma in genere è economica in questi giorni. Comunque penso che il punto riguardante i pool di thread sia ancora valido. Sono uno strumento utile da considerare, ma trovo che la maggior parte delle persone cerchi solo di trovare una ragione per usarle. –