2010-06-13 13 views
14

Quindi ogni volta che scrivo codice, penso sempre alle implicazioni sulle prestazioni. Mi sono spesso chiesto, qual è il "costo" dell'utilizzo di una memcopy rispetto ad altre funzioni in termini di prestazioni?Costo delle prestazioni di un Memcopy in C/C++

Ad esempio, potrei scrivere una sequenza di numeri su un buffer statico e concentrarmi su un frame all'interno del buffer, in modo da mantenere il frame una volta arrivato alla fine del buffer, potrei memcopy tutto all'inizio O posso implementare un algoritmo per ammortizzare il calcolo.

+11

Sei mai andato oltre il pensare alle prestazioni e l'hai misurato? –

+0

Ho, non per memcopy però. – Cenoc

+6

Pensare sempre alle prestazioni è un ottimo modo per scrivere codice scadente (e forse lento). –

risposta

18

memcpy è generalmente ottimizzato per massimizzare la larghezza di banda della memoria di grandi copie. Certo, non è così veloce come evitare una copia completamente, e per le copie corte di dimensioni fisse, l'assegnazione diretta può essere più veloce poiché memcpy ha un codice extra per gestire lunghezze dispari.

Ma quando è necessario copiare un blocco di memoria, è difficile battere memcpy. È altamente portatile e la maggior parte dei compilatori fa di tutto per renderlo veloce, indipendentemente dal fatto che stia usando le istruzioni SIMD o forse inlining.

+1

L'uso della memcpy in C++ dovrebbe essere evitato, dal momento che è una copia "stupida" e possono portare a cose cattive. L'operatore di assegnazione/copiatrice dovrebbe essere usato in alternativa. Inoltre, è necessario eseguire prima un profilo per determinare che si tratta del problema. – Puppy

+13

@DeadMG: molti programmi C++ lavorano su dati "stupidi", che sono definiti "semplici vecchi dati" dallo standard C++ ed è perfettamente sicuro utilizzare memcpy. Nella mia esperienza, il tipo di programmi che non hanno POD sono i programmi che sarebbero meglio scritti in un linguaggio di livello superiore. –

+2

Sì. Potresti * usare memcpy e avvitare totalmente il tuo programma con i tipi non POD. Oppure, * potresti * utilizzare l'operatore di assegnazione, che alla fine si tradurrà in una memcpy per i tipi POD e un programma che funziona per i tipi non POD. – Puppy

1

Beh, in primo luogo - si dovrebbe pensare a prestazioni solo se la copia della memoria è il vostro collo di bottiglia(ed è davvero un caso raro).

In secondo luogo, memcpy viene implementata utilizzando assembler (vedi memcpy.asm) e, credo, è la soluzione di copia di memoria più veloce disponibile.

Anche per menzionare, in generale le chiamate memcpy prime in C++ devono essere evitate, provare a usare wrapper e routine più astratte.

+0

L'assegnazione semplice può essere implementata utilizzando i registri CPU, ma l'uso di memcpy non è il caso. Se l'assegnazione è troppo grande, i registri ricadrebbero comunque al memcpy, quindi è meglio utilizzare l'assegnazione (se applicabile ...) – MindTailor

1

memcpy() copia il contenuto della memoria nell'origine a dest. La copia ovviamente è lineare rispetto alla quantità di elementi nella sorgente. Ciò che costituisce la dimensione ottimale di un elemento è dipendente dalla macchina. In ogni caso un sacco di otimizzazione del compilatore magia nera può applicare a seconda del contesto dell'operazione. In C++ è generalmente più saggio evitare memcpy e utilizzare i costruttori di assegnazione o copia.

+0

In un'architettura moderna, tenendo conto dell'architettura della memoria e degli effetti della cache, la copia quasi certamente non è lineare al numero di elementi. memcpy e copy constructor sta confrontando mele e arance. –

4

Va bene considerare le implicazioni sulle prestazioni, ma non diventare troppo distratto dal vero obiettivo di scrivere un buon codice pulito. Se sei incline a ossessionare le prestazioni anche quando lo conosci meglio, prova a concentrarti su implicazioni di livello superiore e ignora le cose bit per bit come memcpy, che puoi considerare attendibili dal compilatore e dagli autori della libreria.

Generalmente evitare l'ottimizzazione prematura di questo tipo di basso livello perché consuma tempo, gli effetti si gonfiano fino a infettare l'intero programma e, senza misurazioni, non ci si può aspettare di ottenere alcun guadagno in termini di prestazioni.

1

Considerare il libro "Codice completo" di McCormick. Rubare spudoratamente da lì ---

  1. Il miglioramento dell'algoritmo di solito ha il più grande ritorno in termini di prestazioni.

  2. Le semplici istruzioni consentono al compilatore di ottimizzare in modo efficace. Questi hanno un costo basso programmatore. Solitamente aumentano la leggibilità. Sono comunque un valore predefinito basso "dovrebbe".

Come accennato memcpy è già stato ottimizzato ed è spesso molto efficace su blocchi di memoria più grandi.Quindi perché evitarlo se la situazione impone la conservazione dei dati?

In generale non ottimizzare per nessun motivo. Supponi di scrivere un rapporto su un enorme set di dati. Nessun utente si aspetta di avere una risposta istantanea in quello scenario. Iniziano il lavoro e fanno uno spuntino. Quindi se il tuo codice funziona tra 10 minuti o tre minuti non importa. A loro. Thet non se ne accorgerà. E ... scrivono il tuo stipendio.

L'ottimizzazione del programmatore è un enorme costo iniziale. Quindi spendi quel costo solo dove necessario.

+1

In realtà, è il codice completo di Steve Mcconnell –

+0

IT è McConnell. Sono corretto. –

Problemi correlati