2015-05-06 3 views
5

Ich experimentiere mit den tsx-Erweiterungen in haswell, indem ich eine vorhandene mittelgroße (1000er Zeilen) Codebase an die Verwendung von GCC-Transaktionsspeichererweiterungen anpasst (die indirekt haswell tsx in dieser Maschine verwenden) statt grobkörniger Schlösser. Ich benutze die transactional_memory Erweiterungen von GCC und schreibe nicht meine eigene _xbegin/_xend direkt. Ich verwende die ITM_DEFAULT_METHOD = htmmysteriöse rtm abbrechen mit haswell tsx

Ich habe Probleme, es schnell genug zu arbeiten, weil ich hohe Raten von Hardware-Transaktion abbrechen aus mysteriösen Gründen. Wie unten gezeigt, sind diese Abbrüche nicht auf Konflikte oder Kapazitätsbeschränkungen zurückzuführen. Hier

ist der perf Befehl, den ich verwenden, um die Ausfallrate und die zugrunde liegende Ursachen zu quantifizieren:

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 

Also, das Programm einen Code läuft mit Transaktionen in es 30 Millionen mal. Jede Anfrage enthält eine Transaktion gcc __transaction_atomic Block. Es gibt nur einen Thread in diesem Lauf.

Dieser spezielle Befehl perf erfasst die meisten relevanten tsx-Leistungsereignisse, die in Intel software developers manual vol 3 beschrieben sind.

Die Ausgabe von perf stat ist folgende:

   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 

Wie Sie aus der Ausgabe sehen:

  • Die rtm_retired_start Zählung Millionen beträgt 30 (entspricht Eingang Programm)
  • Die rtm_retired_abort Die Anzahl ist ungefähr gleich (keine Commits)
  • Die abort_conflict und abort_capacity zählt sind 0, also sind dies nicht die Gründe. Auch daran erinnern, es ist nur ein Thread läuft, Konflikte sollten selten sein.
  • Die einzigen tatsächlichen führt hier sind die hohen Werte von tx_exec_misc1 und rtm_retired_aborted_misc3, die in der Beschreibung etwas ähnlich sind.

Die Intel manual (Vol 3) definiert rtm_retired_aborted_misc3 Zähler:

Code: C9H 20H

Mnemonik: RTM_RETIRED.ABORTED_MISC3

Beschreibung: Anzahl der Male eines Die RTM-Ausführung wurde aufgrund von unfreundlichen HLE-Anweisungen abgebrochen.

Die Definition für tx_exec_misc1 hat einige ähnliche Wörter:

Code: 5DH 01H

mnemonic: TX_EXEC.MISC1

Beschreibung: Zählt die Häufigkeit, mit der eine Klasse von Anweisungen ausgeführt wurde, die einen Transaktionsabbruch verursachen konnten. Da dies die Anzahl der Ausführungen ist, kann es nicht immer zu einem Transaktionsabbruch kommen.

überprüfte ich die Montagestelle für die Abbrüche für rtm_retired_aborted perf Aufnahme/perf Bericht mit hohen Präzision (PEBS)-Unterstützung. Der Ort hat eine mov Anweisung aus dem Register zu registrieren. Keine seltsamen Instruktionsnamen in der Nähe.

Update:

Hier sind zwei Dinge, die ich seitdem versucht habe:

1) die tx_exec_misc1 und rtm_retired_aborted_misc3 ​​Unterschrift wir uns hier sehen kann beispielsweise dadurch erhalten werden, durch einen Dummy-Block des Formulars

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

oder einer Form

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

In bo In den Fällen sehen die Perf-Zähler ähnlich aus wie ich es sehe. In beiden Fällen weist jedoch die perf report für -e cpu/tx-abort/ auf die intuitiv korrekten Montagelinien hin: eine xabort Anweisung für das erste Beispiel und eine syscall eine für die zweite. In der realen Code-Basis, die perf Bericht zeigt auf einen Stapel schieben gleich zu Beginn einer Funktion:

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

Ich habe auch den gleichen Befehl unter der Intel Software-Entwicklung Emulator laufen. Es stellt sich heraus, dass das Problem in diesem Fall wegfällt: Ich bekomme keinen Abbruch, soweit es die Anwendung betrifft.

+0

Können Sie Ihre Transaktionsschleife buchen? –

+0

Hallo Matthew. Leider ist es eine ziemlich große Schleife (über mehrere Funktionsaufrufe, einige der Funktionen sind textuell groß, obwohl der tatsächliche Ausführungspfad nicht sein muss). – orm

+0

Ist es möglich, dass Sie die Schleife abschneiden, um zu sehen, was das auslöst? Das klingt wie ein zufälliger Systemaufruf irgendwo ... obwohl Ihre perf Ergebnisse etwas bizarr erscheinen. –

Antwort

0

Obwohl es eine Weile lang der Fall war, fand ich diese unbeantwortete Frage während der Suche, also hier ist die Antwort: Dies ist ein Hardware-Bug in Haswell und frühen Broadwell-Chips.

Das von Intel zugewiesene Hardwareratch ist HSW136 und kann nicht mit Microcode-Updates repariert werden. Tatsächlich glaube ich, dass es in Schritt 4 war, dass das Merkmal nicht mehr als verfügbar durch die Anweisung gemeldet wurde, selbst wenn es (fehlerhaftes) Silizium auf dem Chip gab, um es zu implementieren.