Intel x86 0x2e/0x3e prefix Branch prediction rzeczywiście używany?

W najnowszym podręczniku Intel software dev opisuje dwa prefiksy kodu opcode:

Group 2 > Branch Hints

    0x2E: Branch Not Taken
    0x3E: Branch Taken

Pozwalają na jednoznaczne przewidywanie odgałęzień instrukcji skoku (opcodes jakJxx)

Pamiętam, jak czytałem kilka lat temu, że na x86 explicit branch predictionary było zasadniczo no-op w kontekście GCCS branch predicton intrinsics.

Nie jestem teraz pewien, czy te podpowiedzi do gałęzi x86 są nową funkcją, czy też zasadniczo nie są dostępne w praktyce.

Czy ktoś może wyjaśnić?

(to znaczy: czy funkcje przewidywania gałęzi gccs generują te podpowiedzi do gałęzi x86? - a czy obecne procesory Intela ich nie ignorują? - kiedy to się stało?)

Update:

Stworzyłem szybki program testowy:

int main(int argc, char** argv)
{
    if (__builtin_expect(argc,0))
        return 1;

    if (__builtin_expect(argc == 2, 1))
        return 2;

    return 3;
}

Demontuje do:

00000000004004cc <main>:
  4004cc:   55                      push   %rbp
  4004cd:   48 89 e5                mov    %rsp,%rbp
  4004d0:   89 7d fc                mov    %edi,-0x4(%rbp)
  4004d3:   48 89 75 f0             mov    %rsi,-0x10(%rbp)
  4004d7:   8b 45 fc                mov    -0x4(%rbp),%eax
  4004da:   48 98                   cltq   
  4004dc:   48 85 c0                test   %rax,%rax
  4004df:   74 07                   je     4004e8 <main+0x1c>
  4004e1:   b8 01 00 00 00          mov    $0x1,%eax
  4004e6:   eb 1b                   jmp    400503 <main+0x37>
  4004e8:   83 7d fc 02             cmpl   $0x2,-0x4(%rbp)
  4004ec:   0f 94 c0                sete   %al
  4004ef:   0f b6 c0                movzbl %al,%eax
  4004f2:   48 85 c0                test   %rax,%rax
  4004f5:   74 07                   je     4004fe <main+0x32>
  4004f7:   b8 02 00 00 00          mov    $0x2,%eax
  4004fc:   eb 05                   jmp    400503 <main+0x37>
  4004fe:   b8 03 00 00 00          mov    $0x3,%eax
  400503:   5d                      pop    %rbp
  400504:   c3                      retq   
  400505:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  40050c:   00 00 00 
  40050f:   90                      nop
Nie widzę 2E czy 3E ? Może z jakiegoś powodu gcc ich ominęło?
Author: Andrew Tomazos, 2013-01-15

4 answers

Te prefiksy instrukcji nie mają wpływu na nowoczesne procesory (coś nowszego niż Pentium 4). Kosztują one tylko jeden bajt przestrzeni kodowej, a zatem nie generowanie ich jest właściwą rzeczą.

Szczegółowe informacje można znaleźć w podręcznikach optymalizacji Agner Fog, w szczególności 3. Mikroarchitektura: http://www.agner.org/optimize/

"Intel® 64 i IA-32 Architectures Optimization Reference Manual" nie wspomina już o nich w sekcji o optymalizacji gałęzi (sekcja 3.4.1): http://www.intel.de/content/dam/doc/manual/64-ia-32-architectures-optimization-manual.pdf

Te prefiksy są (nieszkodliwym) reliktem architektury Netburst. W optymalizacji all-out, można ich używać do wyrównywania kodu, ale to wszystko, do czego są one dobre w dzisiejszych czasach.

 26
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-15 10:06:50

Gcc ma prawo nie generować prefiksu, ponieważ nie mają one wpływu na wszystkie procesory od Pentium 4.

Ale __builtin_expect ma inne efekty, takie jak przesunięcie nie oczekiwanej ścieżki kodu z pamięci podręcznej-gorące miejsca w kodzie lub decyzje dotyczące inliningu, więc nadal jest to przydatne.

 12
Author: Gunther Piez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-15 09:45:27

Podczas gdy Pentium 4 jest jedyną generacją, która w rzeczywistości respektuje instrukcje branch-hint, większość procesorów ma jakąś formę static branch prediction , która może być użyta do osiągnięcia tego samego efektu. Ta odpowiedź jest nieco styczna z oryginalnym pytaniem, ale myślę, że byłaby to cenna informacja dla każdego, kto wejdzie na tę stronę.

Intel optimisation guide i Agner Fog ' s guide (o których już tu wspomniano) oba mają doskonałe opisy tej funkcji.


Intel ma to do powiedzenia o generacjach nowszych niż Core 2:

Niech kod spadkowy po gałęzi warunkowej będzie prawdopodobnym celem dla gałęzi z celem forward

Więc warunkowe gałęzie, które przeskakują do przodu w kodzie, nie będą brane przez algorytm predykcji statycznej.

Jest to zgodne z tym, co GCC wydaje się wygenerować za pomocą __builtin_expect: 'oczekiwany' return 1 / return 2 Kod jest umieszczany w ścieżkach nie-branych z gałęzi warunkowych, które będą statycznie przewidywane jako nie-brane.

Dodatkowo:

Gałęzie, które nie mają historii w buforze docelowym gałęzi, są przewidywane za pomocą algorytmu predykcji statycznej:

  • / align = "left" /

  • Przewidywać pośrednie gałęzie, które nie będą brane.

Więc w "oczekiwanym" nie wziętym ścieżki, w których GCC umieściło bezwarunkowe jmp s na końcu funkcji, te skoki będą statycznie przewidywane jako zrobione (tzn. nie pominięte).

Intel says:

Niech kod spadkowy po gałęzi warunkowej będzie mało prawdopodobnym celem dla gałęzi z wstecznym celem

Więc warunkowe gałęzie, które przeskakują do tyłu w kodzie są przewidywane do wzięcia, przez algorytm przewidywania statycznego.

Według Agner Fog, Większość Pentium również podąża za tym algorytmem:

Na PPro, P2, P3, P4 i P4E przewiduje się, że instrukcja transferu sterowania, która nie była wcześniej widziana lub nie znajduje się w buforze docelowym gałęzi, przejdzie, jeśli pójdzie do przodu, i zostanie podjęta, jeśli pójdzie do tyłu (np. pętla). Przewidywanie statyczne trwa dłużej niż przewidywanie dynamiczne na tych procesorach.

Jednak rodzina Core 2 (i Pentium M) ma całkowicie inna polityka:

Te procesory nie używają predykcji statycznej. Predyktor po prostu dokonuje losowej prognozy przy pierwszym pojawieniu się gałęzi, w zależności od tego, co stanie się we wpisie BTB przypisanym do nowej gałęzi. Istnieje po prostu 50% szansa na poprawne przewidywanie skoku lub braku skoku, ale przewidywany cel jest prawidłowy.

Podobnie jak procesory AMD :

Przewiduje się, że gałąź nie zostanie podjęta za pierwszym razem jest widziany. Przewiduje się, że gałąź jest zawsze brana po pierwszym pobraniu. Dynamiczne przewidywanie jest używane dopiero po pobraniu gałęzi, a następnie nie. Odgałęzienia podpowiedzi nie mają żadnego wpływu.

Należy wziąć pod uwagę jeden dodatkowy czynnik: Procesory zazwyczaj lubią wykonywać w sposób liniowy, więc nawet prawidłowo-przewidywane brane gałęzie są często droższe niż prawidłowo-przewidywane brane gałęzie.

 7
Author: Cauterite,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-23 19:29:22

Intel® 64 i IA-32 Architectures Software Developer ' s Manual - > Volume 2: Instruction Set Reference, A-Z - > Chapter 2: Instruction Format- > 2.1 Instruction Format for Protected Mode, real-address Mode, and virtual-8086 mode - > 2.1.1 Instruction prefixes

Niektóre wcześniejsze mikroarchitektury używały ich jako podpowiedzi do gałęzi, ale ostatnio pokolenia nie mają i są zarezerwowane do wykorzystania w przyszłości.

 1
Author: smart-rabbit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-24 12:08:31