2010-03-31 18 views

risposta

26

ho usato per un registro in memoria con una dimensione ristretta. Ad esempio, l'applicazione scriverà le voci del registro durante l'elaborazione delle richieste degli utenti. Ogni volta che si verificava un'eccezione (che sarebbe stata distruttiva per l'elaborazione), i record di registro attualmente in memoria venivano scaricati insieme ad esso.

Il vantaggio di un buffer circolare è che non è necessaria una quantità infinita di memoria, poiché le voci meno recenti vengono automaticamente sostituite. La "sfida" è che devi trovare una misura adatta per il tuo caso. Nell'esempio sopra, sarebbe molto sfortunato quando il record di log con le informazioni più vitali sull'eccezione sarebbe già stato sovrascritto.

Alcuni sistemi/applicazioni dispongono di strumenti che consentono di estrarre il contenuto corrente del buffer su richiesta e non solo quando verrà estratto automaticamente (se mai).

Credo che ETW e CLR stress log, tra molti altri kernel del sistema o traccia/registrazione ad alte prestazioni, siano implementati in questo modo.

Il concetto di utilizzo di tali buffer per la traccia/registrazione in memoria è in realtà piuttosto comune (per non dire che questo è l'unico uso - certamente no), perché è molto più veloce dei record scritti su un file/database che potresti non essere mai interessato a meno che non si verifichi un errore. E su una nota correlata, conserva lo spazio del disco rigido.

+8

+1 per "I have usato per .. "invece di" Potresti usarlo per .. " – ryeguy

6

So che questo è un imbroglio, ma wikipedia ha una spiegazione molto buona.

http://en.wikipedia.org/wiki/Circular_buffer

Un buffer circolare, buffer circolare o buffer circolare è una struttura di dati che utilizza un singolo buffer, di dimensioni fisse come se fosse collegato end-to-end. Questo struttura si presta facilmente ad dati bufferizzazione flussi

Un esempio che potrebbe usare un sovrascrivendo buffer circolare è con multimediale. Se il tampone viene impiegato come il buffer limitato nel problema produttore-consumatore, allora è probabilmente desiderato per il produttore (ad esempio, un generatore di audio) per vecchi dati di sovrascrittura se il consumatore (ad esempio, la scheda audio) non è in grado di mantenere temporaneamente . Un altro esempio è il metodo di sintesi guida d'onda digitale che utilizza i buffer circolari su simula in modo efficiente il suono delle corde vibranti o degli strumenti a fiato.

Per quanto riguarda il confronto alle liste di doppio-linked, immagino che realmente dipende da ciò che si sta utilizzando la lista per ... Realizzazione di buffer cirular sembra essere più complessa, per favore (di nuovo) si riferiscono alla wiki pagina; questo spiega l'implementazione, le considerazioni ecc. e mostra anche il codice di esempio.

Grazie, Neil

+0

La risposta alla mia prima domanda SO ha utilizzato un buffer circolare per un generatore audio http://stackoverflow.com/questions/664594/how-to-generate-a-guitar-note –

5

Un buffer circolare è un buon meccanismo per mantenere in modo efficiente una lista scorrevole/mobile di valori/articoli in modo ordinato. Un esempio potrebbe essere il mantenimento di una media mobile degli ultimi N elementi. Supponiamo di voler tenere traccia del costo medio delle ultime 100 operazioni di calcolo di un certo valore. Per fare ciò, è necessario rimuovere il costo più vecchio e aggiungere il costo più recente.

Senza un buffer circolare, un meccanismo costoso per fare ciò (stile C) dovrebbe avere una matrice di 100 elementi. Ogni volta che viene calcolato un nuovo costo, è possibile memmove i 99 elementi verso il basso e inserire quello nuovo nell'ultima posizione. Questo è ovviamente costoso. Usando l'idea di un buffer circolare, devi semplicemente tracciare la "fine" del buffer (posizione 0-99). Contrassegnerebbe la posizione del più vecchio (o più nuovo ... qualsiasi elemento tu scelga). Dopo aver letto il vecchio valore (per l'aggiornamento della media corrente), lo sostituisci con il valore più recente e incrementa la posizione del buffer (se è a 99, lo imposti a 0 ... quindi, la parte circolare).

Il confronto con una lista doppiamente collegata non ha molto senso. Un buffer circolare potrebbe certamente essere implementato con una lista doppiamente collegata (o anche una lista concatenata). Ma confrontarli è un po 'come paragonare mele e arance per così dire.

0

L'ho usato come un modo semplice per implementare la pianificazione round-robin. Fondamentalmente ho avuto un sacco di oggetti diversi che possono produrre un valore che un consumatore potrebbe quindi elaborare. Ho bloccato tutti i produttori in un anello e ho chiesto a ciascuno di loro a turno.

0

Ho usato un buffer circolare nel codice multi-thread. Fondamentalmente, se tutti gli slot sono pieni, i produttori devono attendere. I consumatori elaborano semplicemente gli articoli negli slot che sono "pieni".

Ecco un thread che ho iniziato su di esso. Ha alcuni buoni consigli sull'implementazione.

.NET multi-threaded variable access

11

buffer circolari sono buone per i flussi di dati seriali nei sistemi embedded. I microcontrollori spesso hanno un UART per gestire un byte seriale in arrivo, questi devono essere memorizzati in ordine e trattati in un secondo momento (i byte spesso arrivano a un ritmo più veloce di quello che possono essere gestiti).

Il buffer suddivide in modo efficace la risposta temporale-critica richiesta (quando i byte entrano, in microsecondi) alla risposta non critica ai tempi all'intero messaggio (ad esempio visualizzando il messaggio che è arrivato, in millisecondi), ad es. :

1) Al ricevimento di un byte, la UART può generare un interrupt a cui il software risponde prendendo rapidamente il byte ricevuto e lo inserisce alla fine del buffer.

2) Le routine software in background possono quindi verificare regolarmente se il buffer contiene ancora qualcosa e svuotarlo come richiesto.

Poiché la dimensione del buffer circolare può essere definita come pre-compilazione, la dimensione è limitata. Questo aiuta a migliorare l'efficienza dello spazio e dovrebbe eliminare il danneggiamento della memoria a un compromesso su quanti byte possono essere ricevuti prima che i dati inizino a perdersi.

Problemi correlati