2012-04-04 10 views
83

Questa domanda continua sulla mia domanda qui (su consiglio di Mystical):C prestazioni codice di ciclo [continua]

C code loop performance


Proseguendo la mia domanda, quando uso istruzioni fornite, invece di scalare istruzioni per il codice utilizzando intrinseche sarebbe molto simile:

for(int i=0; i<size; i+=16) { 
    y1 = _mm_load_ps(output[i]); 
    … 
    y4 = _mm_load_ps(output[i+12]); 

    for(k=0; k<ksize; k++){ 
     for(l=0; l<ksize; l++){ 
      w = _mm_set_ps1(weight[i+k+l]); 

      x1 = _mm_load_ps(input[i+k+l]); 
      y1 = _mm_add_ps(y1,_mm_mul_ps(w,x1)); 
      … 
      x4 = _mm_load_ps(input[i+k+l+12]); 
      y4 = _mm_add_ps(y4,_mm_mul_ps(w,x4)); 
     } 
    } 
    _mm_store_ps(&output[i],y1); 
    … 
    _mm_store_ps(&output[i+12],y4); 
    } 

le prestazioni misurata di questo kernel è di circa 5,6 operazioni FP per ciclo, anche se avrei aspettarsi che corrisponda esattamente alle prestazioni 4x della versione scalare, ovvero 4,1,6 = 6,4 FP op per ciclo.

Prendendo la mossa del fattore di peso in considerazione (grazie per la segnalazione), il programma si presenta come:

schedule

Sembra che il programma non cambia, anche se c'è un extra istruzioni dopo l'operazione movss che sposta il valore di peso scalare nel registro XMM e quindi utilizza shufps per copiare questo valore scalare nell'intero vettore. Sembra che il vettore del peso sia pronto per essere utilizzato per lo mulps in tempo, tenendo in considerazione la latenza di commutazione dal carico al dominio in virgola mobile, pertanto non dovrebbe verificarsi alcuna latenza aggiuntiva.

Il movaps (allineato, spostare al sacco), addps & mulps istruzioni che vengono utilizzati in questo kernel (verificato con il codice assembly) hanno la stessa latenza & il throughput come le loro versioni scalari, quindi questo non dovrebbe essere soggetto alcuna latenza più o .

Qualcuno ha un'idea su dove viene speso questo ciclo extra per 8 cicli, supponendo che le prestazioni massime ottenibili da questo kernel siano 6.4 FP ops per ciclo ed è in esecuzione a 5.6 FP ops per ciclo?


A proposito qui è ciò che il gruppo attuale si presenta come:

… 
Block x: 
    movapsx (%rax,%rcx,4), %xmm0 
    movapsx 0x10(%rax,%rcx,4), %xmm1 
    movapsx 0x20(%rax,%rcx,4), %xmm2 
    movapsx 0x30(%rax,%rcx,4), %xmm3 
    movssl (%rdx,%rcx,4), %xmm4 
    inc %rcx 
    shufps $0x0, %xmm4, %xmm4    {fill weight vector} 
    cmp $0x32, %rcx 
    mulps %xmm4, %xmm0 
    mulps %xmm4, %xmm1 
    mulps %xmm4, %xmm2 
    mulps %xmm3, %xmm4 
    addps %xmm0, %xmm5 
    addps %xmm1, %xmm6 
    addps %xmm2, %xmm7 
    addps %xmm4, %xmm8 
    jl 0x401ad6 <Block x> 
… 
+0

Quindi immagino che la domanda ora sia: "Perché l'istruzione' shufps' aggiunge 1 ciclo ogni 1,6 iterazioni? " È una cosa tosta ... – Mysticial

+0

mi aspetterei che non abbia overhead visto che l'output di 'shufps' dovrebbe essere direttamente disponibile all'opzione' multps' dato che è sia il dominio FP – Ricky

+0

Facile da scoprire. Assicurarsi che il vettore del peso non contenga valori di valori denormalizzati. Prova il loop senza le istruzioni shuffle.Non produrrà risultati utili, ma forse troverai le istruzioni che ti costano cicli addizionali (sospetto che lo shuffle, ovviamente). – hirschhornsalz

risposta

3

Provate ad usare EMON profilatura in Vtune, o qualche strumento equivalente come oprof

EMON (Monitoraggio eventi) profiling => come uno strumento basato sul tempo, ma può dirti quale evento di prestazioni sta causando il problema. Anche se, per prima cosa, dovresti iniziare con un profilo basato sul tempo per vedere se c'è una particolare istruzione che salta fuori. (E probabilmente gli eventi correlati che ti dicono quante volte c'era un banco di pensionamento a quell'IP.)

Per utilizzare il profilo EMON, è necessario scorrere un elenco di eventi, che vanno da "i soliti sospetti" a ...

Qui, vorrei iniziare con errori di cache, allineamento. Non so se il processore che stai usando abbia un contatore per i limiti della porta RF - dovrebbe - ma ho aggiunto il profiling EMON molto tempo fa, e non so quanto stiano tenendo il passo aggiungendo eventi appropriati per la microarchitettura.

Potrebbe anche essere possibile che si tratti di un front-end, recupero di istruzioni, stallo. Quanti byte ci sono in queste istruzioni, comunque? Ci sono anche eventi EMON per questo.


Rispondere per commentare che Nehalem VTune non può vedere eventi L3: non vero. Ecco roba che stavo aggiungendo per commentare, ma non andava bene:

In realtà, ci sono contatori di prestazioni per il LL3/L3 $/il cosiddetto Uncore. Sarei immensamente sorpreso se VTune non li supporta. Vedere http://software.intel.com/sites/products/collateral/hpc/vtune/performance_analysis_guide.pdf punti per VTune e altri strumenti come PTU. Infatti, anche senza eventi LL3, come afferma David Levinthal: "il processore Intel® Core ™ i7 ha un" evento di latenza "che è molto simile all'evento EAR Dati processore famiglia Itanium®. Questo evento campiona i carichi , registrando il numero di cicli tra l'esecuzione dell'istruzione e la consegna effettiva dei dati Se la latenza misurata è maggiore della latenza minima programmata in MSR 0x3f6, bit 15: 0, il contatore viene incrementato Contatore bracci di sfioro PEBS meccanismo e sull'evento successivo che soddisfa la soglia di latenza , la latenza misurata, l'indirizzo virtuale o lineare e l'origine dati sono copiati in 3 registri aggiuntivi nel buffer PEBS. Poiché l'indirizzo virtuale è acquisito in una posizione nota, Il driver di campionamento può anche eseguire un virtual alla traduzione fisica e acquisire l'indirizzo fisico. L'indirizzo fisico identifica la posizione della casa NUMA e in linea di principio consente un'analisi dei dettagli delle occupazioni della cache ". Indica inoltre, a pagina 35, eventi VTune come L3 CACHE_HIT_UNCORE_HIT e L3 CACHE_MISS_REMOTE_DRAM. i codici numerici e le loro programma in un'interfaccia di livello inferiore di VTune, ma credo che in questo caso è visibile nell'interfaccia utente abbastanza.


OK, in http://software.intel.com/en-us/forums/showthread.php?t=77700&o=d&s=lr un programmatore VTune in Russia (credo) "spiega" che non è possibile campionare su eventi Uncore

Ha torto - si potrebbe, ad esempio, abilitare solo una CPU, e sa mple significativamente. Credo anche che ci sia la possibilità di contrassegnare i dati mancanti di L3 mentre ritorna alla CPU. Infatti, nel complesso la L3 sa a quale CPU sta restituendo i dati, quindi puoi sicuramente provare. Non si può sapere quale hyperthread, ma ancora una volta è possibile disabilitare, andare in modalità thread singolo.

Ma sembra, come è piuttosto comune, si dovrebbe lavorare AROUND VTune, non con esso, per fare questo.

Provare prima il profilo di latenza. Questo è interamente all'interno della CPU, ed è improbabile che la gente VTune lo abbia incasinato troppo.

E, ripeto, è probabile che il problema sia nel nucleo, non in L3. Quindi VTune dovrebbe essere in grado di gestirlo.


Prova "Ciclo Contabilità" per Levinthal.

+0

Grazie per la tua reazione. Uso VTune per analizzare la mia applicazione, ma il problema con l'architettura nehalem è che la cache L3 appartiene alla parte 'off-core' del core, quindi non ci sono contatori di eventi per le prestazioni disponibili per questa parte. Pertanto è difficile stimare i fallimenti della cache eccetera. – Ricky

+0

In realtà, ci sono contatori delle prestazioni per LL3/L3 $/il cosiddetto Uncore. Sarei immensamente sorpreso se VTune non li supporta. Vedi http://software.intel.com/sites/products/collateral/hpc/vtune/performance_analysis_guide.pdf –

+0

Ho scritto più di quello che si sarebbe potuto inserire nel commento, ho provato a spostarlo alla risposta e ripulire il commento originale, ma i commenti può solo essere modificato per 5 minuti. Versione breve: VTune ti consente di vedere le mancanze della cache L3. Anche senza supporto di Uncore, usando il profilo di latenza - e ha il supporto per Uncore. –