2009-02-08 17 views
6

Mi stavo chiedendo da parecchio tempo su come gestire la memoria nel mio prossimo progetto. Che sta scrivendo una DSL in C/C++.I rifiuti raccolti sono più veloci del C++?

Può essere fatto in uno dei tre modi.

  1. Conteggio di riferimento C o C++.
  2. Rifiuti raccolti C.
  3. In C++, copia classe e strutture da stack a stack e gestisce le stringhe separatamente con qualche tipo di GC.

La comunità probabilmente ha già molta esperienza su ciascuno di questi metodi. Quale sarà più veloce? Quali sono i pro e i contro per ciascuno?

Una domanda secondaria correlata. Il malloc/free sarà più lento dell'allocazione di un grosso blocco all'inizio del programma e su di esso verrà eseguito il mio gestore di memoria? .NET sembra farlo. Ma sono confuso perché non possiamo contare su OS per fare questo lavoro meglio e più velocemente di quello che possiamo fare noi stessi.

risposta

8

Tutto dipende! Questa è una domanda abbastanza aperta. Ha bisogno di un saggio per rispondere!

Hey .. Ecco un qualcuno preparato in precedenza:

http://lambda-the-ultimate.org/node/2552

http://www.hpl.hp.com/personal/Hans_Boehm/gc/issues.html

Dipende quanto è grande gli oggetti sono, quanti di loro ci sono, quanto velocemente stanno venendo assegnate e scartato, quanto tempo si vuole investire ottimizzando e ottimizzando per fare ottimizzazioni. Se conosci i limiti di quanta memoria hai bisogno, per prestazioni veloci, penserei che non puoi davvero battere tutta la memoria che ti serve dal sistema operativo, e poi gestirla tu stesso.

Il motivo per cui può essere lenta allocare memoria dal sistema operativo è che si tratta di un sacco di processi e memoria su disco e in RAM, quindi per ottenere memoria è necessario decidere se c'è abbastanza. Probabilmente, potrebbe dover aprire un'altra memoria di processi da ram a disco in modo che possa darti abbastanza. C'è molto da fare. Quindi gestirlo da solo (o con un heap raccolto GC) può essere molto più rapido di andare al sistema operativo per ogni richiesta. Inoltre, il sistema operativo di solito si occupa di blocchi di memoria più grandi, quindi potrebbe arrotondare la dimensione delle richieste che si fanno nel senso che si potrebbe sprecare memoria.

Hai davvero bisogno di essere super veloce? Un sacco di applicazioni DSL non hanno bisogno di prestazioni non elaborate.Suggerirei di andare con il codice più semplice. Potresti passare una vita a scrivere sistemi di gestione della memoria e preoccuparti quale sia il migliore.

+0

Stai dicendo che tutto questo dipenderà dal linguaggio *, C o C++, uno usa? Dato che in entrambi questi linguaggi, uno deve implementare il GC di sé, penso che non ci siano variazioni per lingua, solo per variazione dell'algoritmo. –

+0

Non completamente sicuro di quello che stai chiedendo. Ma gli stessi algoritmi di gestione della memoria possono essere applicati a entrambe le lingue. Tuttavia in C++ farebbe qualcosa di simile a sostituire l'operatore new e delete per implementarlo. In C non sono sicuro; eventualmente nominare le proprie funzioni e accertarsi di usarle per tutte le assegnazioni. –

4

uh ... Dipende dal modo in cui si si scrive il sistema di garbage collection per il proprio DSL. Né C né C++ sono dotati di una funzione di raccolta dei rifiuti, ma potrebbero essere utilizzati per scrivere un garbage collector molto efficiente o molto inefficiente. A proposito, scrivere una cosa del genere è un compito non banale.

I DSL sono spesso scritti in linguaggi di livello superiore come Ruby o Python, in particolare perché lo scrittore di lingue può sfruttare la garbage collection e altre funzionalità della lingua. C e C++ sono ottimi per scrivere linguaggi completi, di forza industriale, ma è certamente necessario sapere cosa si sta facendo per usarli - la conoscenza di yacc e lex è particolarmente utile qui, ma una buona conoscenza di dynamic memory management è importante anche, come dici tu. Puoi anche dare un'occhiata a keykit, un DSL musicale open source scritto in C, se ti piace ancora l'idea di una DSL in C/C++.

1

Una domanda secondaria correlata. Il malloc/free sarà più lento dell'allocazione di un grosso chuck all'inizio del programma ed eseguirà il mio gestore di memoria su di esso? .NET sembra farlo. Ma sono confuso perché non possiamo contare su OS per fare questo lavoro meglio e più velocemente di quello che possiamo fare noi stessi.

Il problema con il fatto che il sistema operativo gestisce l'allocazione della memoria è che introduce un comportamento indeterministico. Non c'è modo per il programmatore di sapere per quanto tempo il sistema operativo impiegherà a restituire un nuovo blocco di memoria - un'assegnazione può essere piuttosto costosa se la memoria deve essere scaricata sul disco.

La localizzazione di conseguenza potrebbe essere essere una buona idea, soprattutto quando si utilizza un garbage collector di copia. Aumenterà il consumo di memoria, ma l'allocazione sarà veloce perché nella maggior parte dei casi sarà solo un incremento del puntatore.

+0

Il sistema operativo (o in realtà, le librerie, come malloc assegna grandi blocchi e poi li distribuisce pezzo per pezzo al tuo programma) è un allocatore generale. Se riesci a limitare l'allocatore in qualche modo, puoi renderlo più veloce. –

+0

La memoria di lettura/scrittura che è già stata allocata può anche essere piuttosto costosa se è stata eseguita la paginazione su disco. :) – bk1e

3

Con la maggior parte delle implementazioni di garbage collection, l'allocazione può vedere un miglioramento della velocità, ma poi si ha il costo aggiuntivo della fase di raccolta che può essere attivato in qualsiasi punto dell'esecuzione del programma, causando un improvviso (apparentemente casuale) ritardo.

Per quanto riguarda la seconda domanda, dipende dagli algoritmi di gestione della memoria. Saresti al sicuro con l'implementazione malloc predefinita della tua libreria, ma ci sono alternative che vantano prestazioni migliori.

4

Perché i garbage collection raccolti da C sono più veloci del C++? Gli unici garbage collector disponibili per C sono cose piuttosto inefficienti, più progettati per collegare perdite di memoria che per migliorare effettivamente la qualità del tuo codice.

In ogni caso, il C++ ha il potenziale per raggiungere prestazioni migliori con meno codice (si noti che è solo un potenziale. È anche molto possibile scrivere codice C++ che è molto più lento rispetto all'equivalente C).

Considerando lo stato corrente di entrambe le lingue, GC non sta attualmente migliorando le prestazioni del codice. GC può essere reso molto efficiente nelle lingue progettate per questo. C/C++ non sono tra quelli. ;)

A parte questo, è impossibile dirlo. Le lingue non hanno una velocità. Non ha senso chiedere quale lingua sia più veloce. Dipende da 1) il codice specifico, 2) il compilatore che lo compila e 3) il sistema su cui è in esecuzione (hardware e sistema operativo).

malloc è un'operazione piuttosto lenta, molto più lenta degli equivalenti .NET, quindi sì, se si stanno eseguendo molte piccole allocazioni, è possibile che sia meglio allocare un grande pool di memoria una volta e quindi utilizzare blocchi di quella.

Il motivo è che il sistema operativo deve trovare un blocco di memoria gratuito, fondamentalmente seguendo un elenco collegato di tutte le aree di memoria libere. In .NET, una nuova chiamata() non è in pratica altro che spostare il puntatore dell'heap quanti byte è richiesto dall'allocazione.

0

Né C né C++ vi daranno la spazzatura gratuitamente. Quello che ti daranno sono le librerie di allocazione di memoria (che forniscono malloc/free, ecc.). Ci sono molte risorse online per algoritmi per scrivere librerie di garbage collection. Un buon inizio è link text

0

La maggior parte dei linguaggi non GC allocherà e disalloca la memoria in base alle esigenze e non più necessaria.Le lingue di GC di solito assegnano grandi quantità di memoria prima della mano e liberano solo la memoria quando è inattiva e non nel mezzo di un lavoro intensivo, quindi vado a sì se GC calcia al momento giusto.

Il linguaggio di programmazione D è un linguaggio garbage collection e ABI compatibile con C e parzialmente ABI compatibile con C++. This Page mostra alcuni parametri di riferimento tra le prestazioni delle stringhe in C++ e D.

1

Come le persone hanno sottolineato - GC è più veloce da allocare (perché ti dà solo il prossimo blocco sulla sua lista), ma in generale più lento (perché deve compattare l'heap regolarmente, in modo che gli allocati siano veloci).

così - andare per la soluzione di compromesso (che in realtà è dannatamente buono):

È possibile creare i propri mucchi, uno per ogni dimensione dell'oggetto in genere si assegnano (o 4 byte, 8 byte, 16- byte, 32 byte, ecc.) quindi, quando vuoi un nuovo pezzo di memoria, prendi l'ultimo "blocco" nell'heap appropriato. Poiché si esegue la pre-allocazione da questi heap, tutto ciò che è necessario fare quando si assegna è catturare il prossimo blocco libero. Funziona meglio rispetto all'allocatore standard perché si sta sprecando volentieri memoria: se si desidera allocare 12 byte, si lascerà un intero blocco da 16 byte dall'heap da 16 byte. Mantieni una bitmap dei blocchi v utilizzati, in modo che tu possa allocare rapidamente senza sprecare memoria o dover compattare.

Inoltre, poiché si stanno eseguendo diversi heap, i sistemi ad alto parallelismo funzionano molto meglio in quanto non è necessario bloccarli così spesso (ovvero si hanno più blocchi per ogni heap in modo da non ottenere la contesa quasi tanto)

Provalo - lo abbiamo usato per sostituire l'heap standard in un'applicazione molto intensiva, le prestazioni sono aumentate parecchio.

BTW. il motivo per cui gli allocatori standard sono lenti è che cercano di non sprecare memoria, quindi se si allocano 5 byte, 7 byte e 32 byte dall'heap standard, verranno mantenuti quei "limiti". La prossima volta che dovrai allocare, camminerà tra quelli che cercano uno spazio sufficiente per darti quello che hai chiesto. Questo ha funzionato bene per i sistemi a bassa memoria, ma devi solo vedere quanta memoria la maggior parte delle app usa oggi per vedere che i sistemi GC vanno diversamente, e cercare di rendere le allocazioni il più rapide possibile senza preoccuparsi di quanta memoria ci sia sprecato.

1

Il problema ha un sacco di variabili, ma se l'applicazione è scritta con la raccolta dei rifiuti in mente, e se si sfruttano le caratteristiche speciali del Boehm collector, come i diversi inviti di assegnazione per i blocchi che non lo fanno contenere i puntatori, quindi come regola generale la tua applicazione - Avrà interfacce più semplici - Eseguirà un po 'più veloce - Richiederà da 1,2x a 2x lo spazio di un'applicazione simile utilizzando la gestione esplicita della memoria.

Per la documentazione e le prove a sostegno di queste affermazioni, è possibile visualizzare le informazioni sul sito Web di Boehm e anche i numerosi articoli di Ben Zorn sul costo misurato della raccolta dei rifiuti conservativa.

Soprattutto risparmierai un sacco di sforzi e non dovrai preoccuparti di una classe significativa di bug di gestione della memoria.

Il problema di C vs C++ è ortogonale, ma GC sarà sicuramente più veloce del conteggio dei riferimenti, soprattutto quando non è disponibile il supporto del compilatore per il conteggio dei riferimenti.

0

Suggerisco che se si è scritto un programma in cui l'allocazione della memoria e la deallocazione (esplicitamente o GC'ed) è il collo di bottiglia, allora si dovrebbe ripensare la propria architettura, progettazione e implementazione.

0

Se non si desidera gestire in modo esplicito la memoria, non utilizzare C/C++. Esistono molte lingue con il conteggio dei riferimenti o con i garbage collector supportati dal compilatore che probabilmente funzioneranno molto meglio per te.

C/C++ sono progettati in un ambiente in cui il programmatore gestisce la propria memoria. Provare ad aggiornare GC o contare su di essi può essere d'aiuto, ma scoprirai che devi compromettere le prestazioni del GC (perché non ha alcun suggerimento per il compilatore su dove potrebbero essere i puntatori), o tu? Troverò modi nuovi e affascinanti che puoi rovinare i conteggi di riferimento o il GC o qualsiasi altra cosa.

So che sembra una buona idea, ma in realtà, dovresti solo prendere una lingua più adatta all'attività.

Problemi correlati