2009-04-24 19 views
85

Qualcuno ha mai effettivamente utilizzato stackalloc durante la programmazione in C#? Sono consapevole di cosa fa, ma l'unica volta che compare nel mio codice è per caso, perché Intellisense lo suggerisce quando inizio a digitare static, per esempio.Uso pratico della parola chiave `stackalloc`

Anche se non è correlato agli scenari di utilizzo di stackalloc, in realtà faccio una notevole quantità di legacy nelle mie app, quindi ogni tanto potrei ricorrere all'utilizzo del codice unsafe. Tuttavia, tuttavia, di solito trovo il modo di evitare completamente unsafe.

E poiché la dimensione dello stack per un singolo thread in .Net è ~ 1Mb (correggimi se ho torto), sono ancora più riservato dall'uso di stackalloc.

Ci sono alcuni casi pratici in cui si potrebbe dire: "questa è esattamente la quantità corretta di dati e elaborazione per me per andare a rischio e utilizzare stackalloc"?

+2

appena notato che 'System.Numbers' lo utilizza molto https://referencesource.microsoft.com/#mscorlib/system/number.cs,86404b606ba1649f – Slai

risposta

90

L'unico motivo per utilizzare stackalloc è la prestazione (sia per i calcoli che per l'interoperabilità). Usando stackalloc invece di un array assegnato all'heap, si crea meno pressione GC (il GC deve essere eseguito meno), non è necessario appuntare gli array, è più veloce allocare di un array heap, viene automaticamente rilasciato metodo exit (gli array allocati nell'heap vengono deallocati solo quando GC è in esecuzione). Inoltre utilizzando stackalloc invece di un allocatore nativo (come malloc o l'equivalente .Net) si guadagna anche velocità e deallocazione automatica all'uscita dell'ambito.

In termini di prestazioni, se si utilizza stackalloc aumenta notevolmente la possibilità di colpi di cache sulla CPU a causa della località dei dati.

+19

Località dei dati, buon punto! Questo è ciò che raramente si ottiene nella memoria gestita quando si desidera allocare più strutture o array. Grazie! – Groo

+16

Le allocazioni di heap sono in genere più veloci per gli oggetti gestiti rispetto a quelle non gestite perché non esiste alcuna lista libera da attraversare; il CLR incrementa semplicemente il puntatore dell'heap. Per quanto riguarda la località, è probabile che le allocazioni sequenziali finiscano colocate per processi gestiti a lunga esecuzione a causa della compattazione dell'heap. –

20

stackalloc è rilevante solo per codice non sicuro. Per il codice gestito non è possibile decidere dove allocare i dati. I tipi di valore vengono allocati nello stack per impostazione predefinita (a meno che non facciano parte di un tipo di riferimento, nel qual caso vengono allocati nell'heap). I tipi di riferimento sono allocati nell'heap.

La dimensione di stack predefinita per un'applicazione .NET vanilla semplice è 1 MB, ma è possibile modificarla nell'intestazione PE. Se stai iniziando i thread in modo esplicito, puoi anche impostare una dimensione diversa tramite il sovraccarico del costruttore. Per le applicazioni ASP.NET la dimensione dello stack predefinita è solo 256K, che è qualcosa da tenere a mente se si passa da un ambiente all'altro.

+0

È possibile modificare la dimensione dello stack predefinita da Visual Studio? – configurator

+0

@configurator: non per quanto ne so. –

27

Ho usato stackalloc per allocare i buffer per il lavoro DSP [near] in tempo reale. Era un caso molto specifico in cui le prestazioni dovevano essere il più possibile coerenti. Nota c'è una differenza tra coerenza e throughput complessivo - in questo caso non ero preoccupato che le allocazioni dell'heap fossero troppo lente, solo con il non determinismo della garbage collection in quel punto del programma. Non lo userei nel 99% dei casi.

Problemi correlati