2009-03-05 6 views
10

Il massimo teorico di larghezza di banda della memoria per un processore Core 2 con memoria DDR3 a doppio canale è impressionante: secondo lo standard Wikipedia article sull'architettura, 10+ o 20+ gigabyte al secondo. Tuttavia, le chiamate memcpy() non ottengono questo risultato. (3 GB/s è il più alto che abbia mai visto su tali sistemi.) Probabilmente, questo è dovuto al requisito del fornitore del sistema operativo che memcpy() sia ottimizzato per ogni linea di processore in base alle caratteristiche del processore, quindi un'implementazione di stock memcpy() dovrebbe essere ragionevole su un ampio numero di marche e linee.Memcopy/memmove completamente ottimizzati per l'architettura Core 2 o Core i7?

La mia domanda: Esiste una versione liberamente disponibile e altamente sintonizzata per processori Core 2 o Core i7 che possono essere utilizzati in un programma C? Sono sicuro di non essere l'unica persona che ne ha bisogno e sarebbe un grosso spreco di sforzi per tutti ottimizzare la propria memcpy().

risposta

6

Se si specifica/ARCH: SSE2 su MSVC, è necessario fornire una memcpy sintonizzata (almeno, il mio).

In caso contrario, utilizzare SSE allineato carico/archivio intrinseca per copiare la memoria in blocchi di grandi dimensioni, utilizzando un dispositivo Duff di letture vocali dove necessario per gestire la testa e la coda dei dati per ottenere un limite allineato. Avrai bisogno di usare anche gli intrinsechi della gestione della cache per ottenere buone prestazioni.

Il fattore limitante è probabilmente la mancanza della cache e la larghezza di banda del southbridge, piuttosto che i cicli della CPU. Dato che ci sarà sempre molto altro traffico sul bus della memoria, di solito sono felice di ottenere circa il 90% del throughput teorico della larghezza di banda della memoria in tali operazioni.

+1

La memcpia MSVC viene vettorizzata quando queste condizioni sono soddisfatte (all'incirca, non sono un esperto su questo): entrambi gli indirizzi di origine e destinazione sono almeno 8 byte (64 bit) allineati e la dimensione del movimento è sopra una certa soglia. L'allineamento a 64 bit deriva dalla garanzia di MSVC che il proprio 'malloc' restituisce l'allineamento a 64 bit. Quindi, su build a 32 bit, verrà utilizzato SSE2 a 128 bit (con shuffle a 64 bit se necessario) e su build a 64 bit utilizzerà i registri general purpose a 64 bit (con il dispositivo Duff) per eseguire il movimento perché quando è fatto correttamente è "abbastanza veloce" rispetto a SSE2. – rwong

+1

/arch: minimo della CPU requisiti di architettura, uno di: SSE2 - (default) consentire l'uso di istruzioni disponibile con SSE2 abilitato CPU Questo è vc studio di vs2013.update3 visiva ++ uscita . In cui SSE2 è l'impostazione predefinita, in base al mio benchmark, utilizzare/ARCH: SSE2 non migliorerà le prestazioni memcpy, e ho benchmarkato, anche/ARCH: AVX non migliora le prestazioni memcpy. – zhaorufei

2

Si potrebbe scrivere il proprio. Prova a utilizzare lo intel optimising compiler per indirizzare direttamente l'architettura?

Intel produce anche qualcosa chiamato VTune (compilatore e lingua indipendente) per l'ottimizzazione delle applicazioni.

Ecco uno article sull'ottimizzazione di un motore di gioco.

+0

Quanto migliora il compilatore Intel fornisce su gcc con lo stesso switch di ottimizzazione ... ad esempio -O3? –

+0

L'ultima volta che l'ho provato, circa il 35%, ma era qualche anno fa. – Crashworks

+0

sarebbe il downvoter si prega di lasciare un commento. Grazie. –

7

Quando si misura la larghezza di banda si è preso in considerazione che la memcpy era sia una lettura che una scrittura, quindi 3 GB/s di memoria copiata sono in realtà 6 GB/s di larghezza di banda?

Ricorda, la larghezza di banda è massima teorica - l'uso del mondo reale sarà molto più basso. Ad esempio, un errore di pagina e la larghezza di banda scenderanno in MB/s.

memcpy/memmove sono elementi intrinseci del compilatore e di solito vengono inseriti nella lista di movsd (o le istruzioni SSE appropriate se il compilatore può essere indirizzato a tale scopo). Potrebbe essere impossibile migliorare il codice su questo, dal momento che le moderne CPU gestiranno le istruzioni di rep come questo, molto bene.