Domanda

Ho intenzione di partecipare allo sviluppo di un codice scritto in linguaggio C per l'analisi Monte Carlo di problemi complessi.Questo codice alloca enormi quantità di dati in memoria per accelerarne le prestazioni, quindi l'autore del codice ha scelto C invece di C++ sostenendo che con C è possibile creare codice più veloce e più affidabile (per quanto riguarda le perdite di memoria).

Sei d'accordo con questo?Quale sarebbe la tua scelta se avessi bisogno di archiviare 4-16 GB di array di dati in memoria durante il calcolo?

È stato utile?

Soluzione

Sicuramente C ++. Per impostazione predefinita, non c'è alcuna differenza significativa tra i due, ma C ++ fornisce un paio di cose C non si:

  1. costruttori / distruttori. Questi consentono di automatizzare la maggior parte la gestione della memoria, migliorando l'affidabilità.
  2. per classe allocatori. Questi consentono di ottimizzare l'assegnazione in base a come gli oggetti particolari sono progettati e / o usati. Questo può essere particolarmente utile se avete bisogno di un gran numero di piccoli oggetti (per fare un esempio ovvio).

La conclusione è che a questo riguardo, C fornisce alcuna possibilità di un vantaggio rispetto C ++. Nel caso peggiore, si può fare esattamente le stesse cose nello stesso modo.

Altri suggerimenti

C'è una caratteristica di C99 che è assente dal C ++ e che potenzialmente dà significativi guadagni di velocità in pesante codice di elaborazione di calcoli numerici, e che è restrict parola chiave. Se è possibile utilizzare un compilatore C ++ che lo supporta, allora si ha uno strumento in più nel kit, quando si tratta di ottimizzare. E 'solo un guadagno potenziale, però: basta inlining può permettere le stesse ottimizzazioni come restrict e altro ancora. Ha anche a che fare con l'allocazione di memoria.

Se l'autore del codice può dare prova di una differenza di prestazioni tra C e C ++ di codice allocare una matrice 4-16GB, allora (a) Sono sorpreso, ma non male, c'è una differenza, e (b) il numero di tempi è il programma sta per allocare tali grandi array? È il vostro programma di realtà andando a spendere una notevole quantità di memoria tempo allocazione, o è spendendo la maggior parte del suo tempo Accesso di memoria e fare calcoli? Ci vuole molto tempo per davvero do qualsiasi cosa con una matrice di 4 GB, rispetto al tempo impiegato per allocare, e questo significa che si dovrebbe essere preoccupati per la performance di "nulla", non la prestazione di allocazione . Velocisti preoccupano molto la rapidità della loro scendere i blocchi. maratoneti, non tanto.

Dovete anche stare attenti a come si benchmark. Si dovrebbe essere confrontando ad esempio malloc(size) contro new char[size]. Se si prova malloc(size) contro new char[size]() allora è un raffronto non equo in quanto quest'ultima imposta la memoria a 0 e la prima non lo fa. Confronta contro calloc invece, ma anche notare che malloc e calloc sono entrambi disponibili da C ++ nel caso (improbabile) che essi provano misurabile più veloce.

In ultima analisi, però, se l'autore "possiede" o avviato il progetto, e preferisce scrivere in C piuttosto che C ++, allora dovrebbe non giustificano tale decisione con prestazioni dichiarate probabilmente-spuri, dovrebbe giustificarlo dicendo " io preferisco C, ed è quello che sto usando". Di solito, quando qualcuno fa una richiesta del genere sulle prestazioni lingua, e si scopre sui test di non essere vero, si scopre che le prestazioni non è la vera ragione per la preferenza della lingua. Dimostrando la falsa pretesa non sarà effettivamente causare l'autore di questo progetto per iniziare improvvisamente simpatia C ++.

Non c'è una vera differenza tra C e C ++, in termini di allocazione di memoria. C ++ ha dati più 'nascosti', come ad esempio i puntatori virtuali e così via, se si è scelto di avere metodi virtuali sul vostro oggetti. Ma l'assegnazione di una serie di caratteri è altrettanto costoso in C come in C ++, in effetti, sono probabilmente entrambi utilizzando malloc per farlo. In termini di prestazioni, C ++ richiede un costruttore per ciascun oggetto dell'array. Si noti che questo è fatto solo se ce n'è uno, il costruttore di default non fa nulla ed è ottimizzato via.

Fino a quando si sta preallocare pool di dati, al fine di evitare la frammentazione della memoria, si dovrebbe essere pronti per partire. Se si dispone di semplici POD-struct senza metodi virtuali, e senza costruttori, non c'è alcuna differenza.

L'unica cosa a sfavore del C++ è la sua complessità aggiuntiva - combinalo con un programmatore che lo usa in modo errato e puoi facilmente rallentare notevolmente.L'uso di un compilatore C++ senza funzionalità C++ ti darà le stesse prestazioni.Usando correttamente il C++, hai alcune possibilità di essere più veloce.

La lingua non è un tuo problema, l'allocazione e l'attraversamento di array di grandi dimensioni lo è.

Il principale errore mortale che potresti commettere nell'allocazione (in entrambe le lingue) è allocare 16 GB di memoria, inizializzandola a zero, solo per riempirla successivamente con i valori effettivi.

I maggiori guadagni in termini di prestazioni che mi aspetterei dalle ottimizzazioni algoritmiche che migliorano la località di riferimento.

A seconda del sistema operativo sottostante, potresti anche influenzare gli algoritmi di memorizzazione nella cache, ad es.indicando che un intervallo di memroy viene elaborato solo in sequenza.

Per allocare dati grezzi, non ci dovrebbe essere una differenza tra C e C ++ su molti sistemi, come avviene normalmente entrambi utilizzano gli stessi meccanismi di libreria runtime. Mi chiedo se questa è stata la classica trappola punto di riferimento dove hanno anche misurato il tempo di esecuzione delle chiamate costruttore in C ++ e convenientemente dimenticato su come includere l'esecuzione di qualsiasi tipo di codice di inizializzazione in C.

Inoltre, il "più affidabile (per quanto riguarda le perdite di memoria)" argomento non regge l'acqua se si sta usando RAII in C ++ (come si dovrebbe). A meno che qualcuno sta riferendo a rendere trapelare in modo più affidabile, utilizzando Raii, puntatori intelligenti e classi contenitore ridurranno il rischio di fughe di notizie, non aumentarlo.

Le mie preoccupazioni principali con l'allocazione di memoria che molto sarebbe duplice:

  • Se stai ricevendo vicino al limite di memoria fisica sulle macchine si sta eseguendo la simulazione Monte Carlo, è un buon modo per ridurre le prestazioni, perché il disco potrebbe anche iniziare al thrash quando il sistema di memoria virtuale ha bisogno di iniziare paging molto. La memoria virtuale non è "libero", anche se un sacco di gente pensa che sia.
  • layout di dati deve essere considerato con attenzione per massimizzare l'utilizzo della cache del processore, altrimenti si parte perdono i vantaggi di mantenere i dati nella memoria principale, in primo luogo.

Se allocazione di memoria è un collo di bottiglia in tale codice, vorrei suggerire invece la riprogettazione, non cambiare la lingua per l'allocazione più veloce. Se si alloca la memoria una volta e poi eseguire un sacco di calcoli mi aspetterei quei calcoli di essere un collo di bottiglia. Se il costo di allocazione è significativo, qualcosa che non va qui.

È possibile utilizzare la famiglia di funzioni C allocazione di memoria in C ++ anche: sia il malloc standard free, realloc per ingrandire / shring array e alloca allocare memoria sullo stack

.

Se si va con new, sarà allocare più memoria di quanto è necessario (per lo più durante il debug) e fare controlli supplementari per la coerenza. Sarà anche chiamare il costruttore per le classi. In un comunicato (-O3) costruire la differenza sarà trascurabile per la maggior parte delle applicazioni.

Ora che cosa new porta che malloc non è il new sul posto. È possibile preallocare un buffer e quindi utilizzare il new sul posto per mettere la tua struttura in quel buffer, rendendo così "allocazione" è istantanea.

Tutto sommato, non vorrei stare lontano da C a causa di problemi di prestazioni. Se non altro, il codice sarà più efficace perché le classi passano il puntatore this nei registri invece di parametri come nel C equivalente. Un vero e proprio motivo di stare lontano dalla C è la dimensione del runtime C ++. Se si sviluppano i programmi per i sistemi embedded o programmi di boot-caricato, non è possibile incorporare il ~ runtime 4mb. Per le applicazioni normali Tuttavia, questo non farà la differenza.

Se avete bisogno di memorizzare 4-16 GB di array di dati in memoria durante il calcolo e la vostra macchina ha solo 2 GB di memoria fisica, e poi?

Cosa fare se la macchina ha 16 GB di memoria fisica? Il sistema operativo non prendono memoria fisica?

Il sistema operativo anche permettere uno spazio di indirizzi di 4 GB, 16 GB, etc?

Suggerisco che, se le prestazioni sono un vincolo implementazione primario, quindi comprendere come le piattaforme, che sono destinati ad essere utilizzati, funzione ed eseguire sono molto più significativo rispetto alla domanda di qualsiasi differenza di prestazioni misurabile tra C e C ++ dato ambienti identici e gli algoritmi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top