C'è uno svantaggio nell'assegnare un'enorme quantità di stack per un singolo array in un sistema embedded?

12

Di solito non ho alcun problema nel decidere se alcuni dati debbano essere globali, statici o in pila (nessuna allocazione dinamica qui, quindi nessun uso dell'heap). Ho anche letto alcuni Q / A come questo ma la mia domanda è più specifico poiché comporta una quantità enorme di dati, enorme rispetto alla memoria di sistema.

Sto lavorando a un codice esistente che cerco di migliorare (progettazione, possibili problemi, prestazioni, ecc.). Questo codice viene eseguito su un vecchio MCU a 8 bit con solo 4KB di RAM . In questo codice mi trovo ad affrontare l'uso di un array di quasi 1 KB (sì, 1 KB su un sistema 4KB RAM ). Viene utilizzato ogni byte di questo array, non è questa la domanda. Il problema è che questa matrice è una matrice statica nel file in cui è dichiarata, quindi il suo ciclo di vita è uguale a quello del programma (vale a dire può essere considerato infinito).

Tuttavia, dopo aver letto il codice, ho appena scoperto che questo array non ha bisogno di un ciclo di vita infinito, è costruito e gestito in modo completamente procedurale, quindi dovremmo essere in grado di dichiararlo solo nella funzione dove è usato, in questo modo sarebbe in pila, e quindi salveremmo questo 1KB di RAM.

Ora la domanda: sarebbe una buona idea? Dal punto di vista del design, se non ha bisogno di un ciclo di vita infinito / globale, appartiene allo stack. Ma hey, questo è 1KB su 4KB, non c'è alcun svantaggio nell'assegnare il 25% della RAM in questo modo? (che potrebbe essere il 50% o più dello stack)

Qualcuno potrebbe condividere qualche esperienza con questo tipo di situazione, o qualcuno pensa a qualche valido motivo per non mettere questo array in pila? Sto cercando gli inconvenienti tecnici e commenti sul design.

L'unica cosa che sono consapevole è che devo assicurarmi di avere effettivamente 1KB di stack libero quando si accede a questa funzione. Forse è tutto quello che devo curare, forse no.

    
posta Tim 11.10.2016 - 13:56
fonte

5 risposte

7

The only thing I'm conscious is that I have to make sure I actually have 1KB of stack free when entering this function.

Sì, e questo è un strong vincolo. Sarà meglio accertarsi staticamente di quanto tu abbia uno spazio così grande disponibile in pila. Se il codice è piccolo, se stai utilizzando un GCC recente per compilare il tuo codice, consulta questo .

A proposito, alcuni microprocessori economici potrebbero utilizzare un frame di chiamata "grande" più costoso di uno "normale" (ad esempio perché il loro set di istruzioni favorirebbe un offset di un byte dal puntatore dello stack). YMMV.

Inoltre, se stai codificando in C e se ritieni che il tuo array di grandi dimensioni possa avere il suo spazio riutilizzato per altri scopi, potresti considerare di farlo diventare membro del sindacato (con una variabile globale di% tipounion). Sì, è abbastanza brutto.

In alternativa, potresti prendere in considerazione la codifica di un allocatore di heap primitivo adatto alla tua applicazione (e potrebbe avere un'API diversa da malloc e free ....).

    
risposta data 11.10.2016 - 14:09
fonte
6

Le persone tendono ad essere prudenti con un grande stack, perché cresce all'indietro nella RAM e sovrascrive i valori delle variabili, portando a comportamenti inspiegabili. Diventa ancora peggio, perché è necessario conoscere l'indirizzo del puntatore dello stack più basso possibile e sottrarre la dimensione da allocare quando si immette la routine.

Questo è tutto un lavoro per la gestione della memoria hardware (dovrebbe generare trap o errori quando si verifica un overflow dello stack) o per il compilatore, dato che ha caratteristiche per questo tipo di analisi.

Altrimenti, puoi fare ciò che vuoi con la tua RAM.

    
risposta data 11.10.2016 - 14:17
fonte
4

Come le risposte precedenti hanno sottolineato, vorrei anche prima raccomandare di lasciare l'array statico se si adatta alla memoria. Nella maggior parte dei casi, è molto più importante avere un'impronta di memoria deterministica, anche se ciò significa che "rifiuti" la memoria per le variabili non utilizzate tutto il tempo. Mettere array di grandi dimensioni sul tuo stack lo farà fin troppo facilmente, e lo stack overflow tende a causare problemi difficili da trovare e difficili da riprodurre (se non puoi usare MMU per proteggere lo stack).

Il suggerimento di condividere il blocco con altri dati con unione è IMO valido, sebbene possa anche essere fonte di problemi difficili da trovare, se si individuano variabili errate in esso.

Se si sta esaurendo la memoria e si ha disperatamente bisogno di rendere le variabili di vita più breve per condividerla, prima di spostare la matrice in pila, vorrei prendere in considerazione l'aggiunta di allocazione dinamica della memoria, anche se ha i suoi svantaggi. In questo caso potrebbe non essere una risposta, in quanto l'array sembra abbastanza grande rispetto alla memoria disponibile.

    
risposta data 11.10.2016 - 20:42
fonte
1

Hai un'altra opzione se hai qualche tipo di memoria flash. Puoi scambiare la velocità di accesso per ram memorizzando i tuoi dati in flash e leggendo & cercando lì. Dovresti solo caricare un record alla volta nella ram. Sarà leggermente più complicato se è necessario essere in grado di aggiornare i record. Avrai bisogno di un meccanismo segmentato di usura. Ho fatto questo in passato e incluso un indice per accelerare l'accesso.

    
risposta data 12.10.2016 - 23:48
fonte
1

Soprattutto quando si lavora con sistemi embedded, si vuole che gran parte dei possibili errori si verifichino in fase di compilazione e niente mai fallisca in fase di esecuzione (sarebbe bello se potessimo ottenere ciò, anche se ...) .

Creare array di grandi dimensioni che potresti avere bisogno in stati arbitrari del tuo programma assegnato staticamente fa esattamente questo - Il linker ti avvertirà alla fine "questo non si adatta alla RAM", mentre l'allocazione dello stack semplicemente renderebbe il tuo programma in crash con - overflow di stack di debug.

    
risposta data 31.10.2016 - 10:28
fonte

Leggi altre domande sui tag