Questa domanda ha ora quattro anni e sono un po 'sorpresa che nessuno abbia menzionato la larghezza di banda della memoria. CPU-Z segnala che la mia macchina ha una RAM PC3-10700. Che la RAM abbia un'ampiezza di banda di picco (ovvero velocità di trasferimento, velocità effettiva, ecc.) Di 10700 MByte/sec. La CPU nella mia macchina è una CPU i5-2430M, con una frequenza di picco del turbo di 3 GHz.
In teoria, con una CPU veloce e infinitamente la mia RAM, memcpy potrebbe andare a 5300 MByte/sec, vale a dire la metà di 10700 perché memcpy deve leggere e poi scrivere alla RAM. (modifica: come ho sottolineato, questa è un'approssimazione semplicistica).
D'altra parte, immagina di avere una RAM infinitamente veloce e una CPU realistica, cosa potremmo ottenere? Usiamo la mia CPU 3 GHz come esempio. Se potesse eseguire una lettura a 32 bit e una scrittura a 32 bit per ogni ciclo, potrebbe trasferire 3e9 * 4 = 12000 MByte/sec. Questo sembra facilmente alla portata di una CPU moderna. Già, possiamo vedere che il codice in esecuzione sulla CPU non è proprio il collo di bottiglia. Questo è uno dei motivi per cui le macchine moderne hanno cache di dati.
Siamo in grado di misurare ciò che la CPU può realmente fare eseguendo il benchmarking di memcpy quando sappiamo che i dati sono memorizzati nella cache. Fare questo con precisione è poco pratico. Ho creato una semplice app che ha scritto numeri casuali in un array, li abbiamo memcpy in un altro array, quindi ha eseguito il checksum dei dati copiati. Ho fatto un passo attraverso il codice nel debugger per assicurarmi che il compilatore intelligente non avesse rimosso la copia. La modifica della dimensione dell'array altera le prestazioni della cache: piccoli array si adattano alla cache, quelli grandi meno. Ho i seguenti risultati:
- 40 KByte array: 16000 MB/s
- 400 KByte array: 11000 MB/s
- 4000 matrici KByte: 3100 MByte/sec
Ovviamente, la mia CPU può leggere e scrivere più di 32 bit per ciclo, dal momento che 16000 è più del 12000 che ho calcolato teoricamente sopra. Ciò significa che la CPU è ancora meno un collo di bottiglia di quanto pensassi. Ho usato Visual Studio 2005 e, passando all'applicazione standard di memcpy, vedo che usa le istruzioni movqda sulla mia macchina. Immagino che questo possa leggere e scrivere 64 bit per ciclo.
Il bel codice pubblicato hamagibashi raggiunge 4200 MByte/sec sulla mia macchina, circa il 40% più veloce rispetto all'implementazione VS 2005. Immagino sia più veloce perché usa l'istruzione prefetch per migliorare le prestazioni della cache.
In sintesi, il codice in esecuzione sulla CPU non è il collo di bottiglia e l'ottimizzazione del codice comporterà solo piccoli miglioramenti.
puoi scrivere il tuo codice in modo che la copia non sia richiesta in primo luogo? – Ron
Ron, no, non posso :( – horseyguy
Se riesci a ottenere una sospensione del compilatore Intel potresti avere migliori possibilità di conversione dell'ottimizzatore in istruzioni per la cpu vettoriale –