2015-05-06 10 views
5

Sto sperimentando le estensioni tsx in haswell, adattando un codice base esistente di dimensioni medie (1000 di righe) all'utilizzo di estensioni di memoria transazionale GCC (che utilizzano indirettamente tsx haswell in questa macchina) invece di ciocche a grana grossa. Sto usando le estensioni transactional_memory di GCC, non scrivendo direttamente _xbegin/_xend. Sto usando ITM_DEFAULT_METHOD = htmmisterioso abortire utilizzando haswell tsx

Ho problemi a farlo funzionare abbastanza velocemente perché ottengo alti tassi di interruzione della transazione hardware per motivi misteriosi. Come mostrato di seguito, tali aborti non sono dovuti a conflitti né a limitazioni di capacità.

Ecco il comando perf ho usato per quantificare il tasso di fallimento e cause:

perf stat \ 
-e cpu/event=0x54,umask=0x2,name=tx_mem_abort_capacity_write/ \ 
-e cpu/event=0x54,umask=0x1,name=tx_mem_abort_conflict/ \ 
-e cpu/event=0x5d,umask=0x1,name=tx_exec_misc1/ \ 
-e cpu/event=0x5d,umask=0x2,name=tx_exec_misc2/ \ 
-e cpu/event=0x5d,umask=0x4,name=tx_exec_misc3/ \ 
-e cpu/event=0x5d,umask=0x8,name=tx_exec_misc4/ \ 
-e cpu/event=0x5d,umask=0x10,name=tx_exec_misc5/ \ 
-e cpu/event=0xc9,umask=0x1,name=rtm_retired_start/ \ 
-e cpu/event=0xc9,umask=0x2,name=rtm_retired_commit/ \ 
-e cpu/event=0xc9,umask=0x4,name=rtm_retired_aborted/pp \ 
-e cpu/event=0xc9,umask=0x8,name=rtm_retired_aborted_misc1/ \ 
-e cpu/event=0xc9,umask=0x10,name=rtm_retired_aborted_misc2/ \ 
-e cpu/event=0xc9,umask=0x20,name=rtm_retired_aborted_misc3/ \ 
-e cpu/event=0xc9,umask=0x40,name=rtm_retired_aborted_misc4/ \ 
-e cpu/event=0xc9,umask=0x80,name=rtm_retired_aborted_misc5/ \ 
./myprogram -th 1 -reps 3000000 

Così, il programma viene eseguito un codice con le transazioni in esso 30 milioni di volte. Ogni richiesta implica una transazione gcc __transaction_atomic blocco. C'è solo un thread in questa corsa.

Questo particolare comando perf acquisisce la maggior parte degli eventi di prestazioni tsx rilevanti descritti nello Intel software developers manual vol 3.

L'uscita dal perf stat è la seguente:

   0 tx_mem_abort_capacity_write         [26.66%] 
      0 tx_mem_abort_conflict          [26.65%] 
    29,937,894 tx_exec_misc1            [26.71%] 
      0 tx_exec_misc2            [26.74%] 
      0 tx_exec_misc3            [26.80%] 
      0 tx_exec_misc4            [26.92%] 
      0 tx_exec_misc5            [26.83%] 
    29,906,632 rtm_retired_start           [26.79%] 
      0 rtm_retired_commit           [26.70%] 
    29,985,423 rtm_retired_aborted           [26.66%] 
      0 rtm_retired_aborted_misc1         [26.75%] 
      0 rtm_retired_aborted_misc2         [26.73%] 
    29,927,923 rtm_retired_aborted_misc3         [26.71%] 
      0 rtm_retired_aborted_misc4         [26.69%] 
      176 rtm_retired_aborted_misc5         [26.67%] 

    10.583607595 seconds time elapsed 

Come si può vedere dalla uscita:

  • Il conteggio rtm_retired_start è di 30 milioni di euro (partite di ingresso al programma)
  • Il rtm_retired_abort il conteggio è quasi lo stesso (nessun commit)
  • Il abort_conflict eI conteggisono 0, quindi questi non sono i motivi. Inoltre, ricorda che è solo un thread in esecuzione, i conflitti dovrebbero essere rari.
  • Gli unici contatti effettivi qui sono i valori elevati di tx_exec_misc1 e rtm_retired_aborted_misc3, che sono in qualche modo simili nella descrizione.

Il manuale Intel (vol 3) definisce rtm_retired_aborted_misc3 contatori:

codice: C9H 20H

mnemonico: RTM_RETIRED.ABORTED_MISC3

descrizione: Numero di volte in cui un Esecuzione RTM interrotta a causa di istruzioni ostili HLE.

La definizione di tx_exec_misc1 ha alcune parole simili:

codice: 5DH 01H

mnemonico: TX_EXEC.MISC1

descrizione: conta il numero di volte in cui è stata eseguita una classe di istruzioni che può causare una interruzione di transazione. Poiché questo è il conteggio dell'esecuzione, potrebbe non sempre causare un'interruzione transazionale.

ho controllato la posizione di montaggio per l'Aborts utilizzando perf rapporto record/perf utilizzando il supporto ad alta precisione (PEBS) per rtm_retired_aborted. La posizione ha un'istruzione mov dal registro per la registrazione. Nessun nome di istruzioni strano visto nelle vicinanze.

Aggiornamento:

Qui ci sono due cose che ho provato da allora:

1) il tx_exec_misc1 e rtm_retired_aborted_misc3 ​​firma ci vediamo qui può essere ottenuto, ad esempio, da un blocco fittizio della forma

for (int i = 0; i < 10000000; i++){ 
    __transaction_atomic{ 
    _xabort(1); 
    } 
} 

o una forma

for (int i = 0; i < 10000000; i++){ 
    __transaction_atomic{ 
    printf("hello"); 
    fflush(stdout); 
    } 
} 

In bo casi, i segnalini perf sono simili a quelli che vedo. Tuttavia, in entrambi i casi lo perf report per -e cpu/tx-abort/ punta alle linee di assemblaggio intuitivamente corrette: un'istruzione xabort per il primo esempio e uno syscall per il secondo. Nel vero e proprio codice di base, i punti di rapporto perf a una pila spingono proprio all'inizio di una funzione:

  : 00000000004167e0 <myns::myfun()>: 
    100.00 :  4167e0:  push %rbp 
     0.00 :  4167e1:  mov %rsp,%rbp 
     0.00 :  4167e4:  push %r15 

ho anche eseguire lo stesso comando sotto lo sviluppo emulatore software Intel. Si scopre che il problema si risolve in questo caso: non ho alcun dubbio per quanto riguarda l'applicazione.

+0

Potresti pubblicare il tuo ciclo transazionale? –

+0

Ciao Matthew. Sfortunatamente è un loop piuttosto grande (si estende su più chiamate di funzione, alcune delle funzioni sono testualmente grandi, anche se il percorso di esecuzione effettivo non deve essere). – orm

+0

È possibile iniziare a tagliare il ciclo per vedere che cosa sta causando questo? Sembra una chiamata di sistema accidentale da qualche parte ... anche se i tuoi risultati perf sembrano un po 'bizzarri. –

risposta

0

Anche se è stato così per un po ', ho trovato questa domanda senza risposta durante la ricerca, quindi ecco la risposta: questo è un bug hardware in Haswell e nei primi chip Broadwell.

L'errore hardware specifico assegnato da Intel è HSW136 e non è risolvibile tramite gli aggiornamenti microcodice. In effetti, penso che era in fase 4 che la funzione non era più segnalata come disponibile dall'istruzione cpuid, anche quando sul chip era presente del silicio (difettoso) per implementarlo.

Problemi correlati