Zestaw instrukcji manipulacji bitami x86
Zestawy instrukcji manipulacji bitami ( zestawy BMI ) są rozszerzeniami architektury zestawu instrukcji x86 dla mikroprocesorów firm Intel i AMD . Celem tych zestawów instrukcji jest poprawa szybkości manipulacji bitami . Wszystkie instrukcje w tych zestawach nie są SIMD i działają tylko na rejestrach ogólnego przeznaczenia .
Firma Intel publikuje dwa zestawy: BMI (obecnie określany jako BMI1) i BMI2; oba zostały wprowadzone z Haswell z funkcjami dopasowania BMI1 oferowanymi przez zestaw instrukcji ABM firmy AMD i rozszerzeniem BMI2. Kolejne dwa zestawy zostały opublikowane przez AMD: ABM ( Advanced Bit Manipulation , który jest również podzbiorem SSE4a zaimplementowanym przez Intela jako część SSE4.2 i BMI1) oraz TBM ( Trailing Bit Manipulation , rozszerzenie wprowadzone z procesorami opartymi na Piledriver jako rozszerzenie BMI1, ale ponownie spadło w Zen procesory bazowe).
ABM (zaawansowana manipulacja bitami)
Firma AMD jako pierwsza wprowadziła instrukcje, które obecnie tworzą BMI1 firmy Intel, jako część zestawu instrukcji ABM ( Advanced Bit Manipulation ), a później dodała obsługę nowych instrukcji BMI2 firmy Intel. AMD reklamuje dziś dostępność tych funkcji za pomocą flag procesorów BMI1 i BMI2 firmy Intel i instruuje programistów, aby odpowiednio je ukierunkowali.
Podczas gdy Intel uważa POPCNT
za część SSE4.2 i LZCNT
za część BMI1, zarówno Intel, jak i AMD reklamują obecność tych dwóch instrukcji indywidualnie. POPCNT
ma oddzielną flagę CPUID o tej samej nazwie, a Intel i AMD używają flagi ABM
AMD do wskazania obsługi LZCNT (ponieważ
LZCNT
w połączeniu z BMI1 i BMI2 uzupełnia rozszerzony zestaw instrukcji ABM).
Kodowanie | Instrukcja | Opis |
---|---|---|
F3 0F B8 /r
|
POPCNT
|
Liczba ludności |
F3 0F BD /r
|
LZCNT
|
Liczą się zera wiodące |
LZCNT
jest powiązany z instrukcją Bit Scan Reverse ( BSR
), ale ustawia flagi ZF (jeśli wynik wynosi zero) i CF (jeśli źródłem jest zero) zamiast ustawiać ZF (jeśli źródło wynosi zero). Ponadto generuje określony wynik (rozmiar operandu źródłowego w bitach), jeśli operand źródłowy wynosi zero. Dla argumentu niezerowego suma LZCNT
i BSR
to szerokość bitowa argumentu minus 1 (na przykład, jeśli argument 32-bitowy to 0x000f0000
, LZCNT daje 12, a BSR daje 19).
Kodowanie LZCNT
jest takie, że jeśli ABM nie jest obsługiwane, zamiast tego wykonywana jest instrukcja BSR
.
BMI1 (zestaw instrukcji manipulacji bitami 1)
Poniższe instrukcje dotyczą bitu BMI
w CPUID. Intel oficjalnie uważa LZCNT
za część BMI, ale reklamuje obsługę LZCNT za pomocą flagi funkcji
ABM
CPUID. BMI1 jest dostępny w procesorach AMD Jaguar , Piledriver i nowszych oraz w procesorach Intel Haswell i nowszych.
Kodowanie | Instrukcja | Opis | Równoważne wyrażenie C |
---|---|---|---|
VEX.LZ.0F38 F2 /r
|
ORAZ N
|
Logiczne i nie |
~x i y
|
VEX.LZ.0F38 F7 /r
|
BEXTR
|
Ekstrakt pola bitowego (z rejestrem) |
(źródło >> początek) & ((1 << długość) - 1)
|
VEX.LZ.0F38 F3 /3
|
BLSI
|
Wyodrębnij najniższy zestaw izolowanych bitów |
x & -x
|
VEX.LZ.0F38 F3 /2
|
BLSMSK
|
Podnieś maskę do najniższego ustawionego bitu |
x ^ (x - 1)
|
VEX.LZ.0F38 F3 /1
|
BLSR
|
Zresetuj najniższy ustawiony bit |
x & (x - 1)
|
F3 0F pne /r
|
TZCNT
|
Policz liczbę końcowych bitów zerowych |
0
0
0 31 + ( ! x ) - (( ( x & - x ) & 0x0000FFFF ) ? 16 : ) - ((( x & - x ) & 0x00FF00FF ) ? 8 : ) - ((( x & - x ) & 0x0F0F0F0F ) ? 4 :) - _
0
0 ((( x & - x ) & 0x33333333 ) ? 2 : ) - ((( x & - x ) & 0x55555555 ) ? 1 : )
|
TZCNT
jest prawie identyczny z instrukcją Bit Scan Forward ( BSF
), ale ustawia flagi ZF (jeśli wynik wynosi zero) i CF (jeśli źródło ma wartość zero) zamiast ustawiać ZF (jeśli źródło ma wartość zero). Dla argumentu niezerowego wynik TZCNT
i BSF
jest równy.
Podobnie jak w przypadku LZCNT
, kodowanie TZCNT
jest takie, że jeśli BMI1 nie jest obsługiwane, zamiast tego wykonywana jest instrukcja BSF .
BMI2 (zestaw instrukcji manipulacji bitami 2)
Intel wprowadził BMI2 wraz z BMI1 w swojej linii procesorów Haswell. Tylko AMD wyprodukowało procesory obsługujące BMI1 bez BMI2; BMI2 jest obsługiwane przez architekturę AMD Excavator i nowsze.
Kodowanie | Instrukcja | Opis |
---|---|---|
VEX.LZ.0F38 F5 /r
|
BZHI
|
Zerowe wysokie bity zaczynające się od określonej pozycji bitu [src & (1 << inx)-1]; |
VEX.LZ.F2.0F38 F6 /r
|
MULX
|
Mnożenie bez znaku bez wpływu na flagi i dowolne rejestry docelowe |
VEX.LZ.F2.0F38 F5 /r
|
PDEP
|
Deponowanie bitów równoległych |
VEX.LZ.F3.0F38 F5 /r
|
PEXT
|
Ekstrakt bitów równoległych |
VEX.LZ.F2.0F3A F0 /r ib
|
RORX
|
Obróć logicznie w prawo bez wpływu na flagi |
VEX.LZ.F3.0F38 F7 /r
|
SARX
|
Przesuń arytmetykę w prawo bez wpływu na flagi |
VEX.LZ.F2.0F38 F7 /r
|
SHRX
|
Przesuń logicznie w prawo bez wpływu na flagi |
VEX.LZ.66.0F38 F7 /r
|
SHLX
|
Przesuń logicznie w lewo bez wpływu na flagi |
Równoległe wkładanie i pobieranie bitów
PDEP i PEXT to nowe uogólnione instrukcje kompresji i rozszerzenia
na
poziomie bitów. Biorą dwa wejścia; jedno jest źródłem, a drugie selektorem. Selektor to mapa bitowa wybierająca bity, które mają być spakowane lub rozpakowane. PEXT
kopiuje wybrane bity ze źródła do sąsiednich bitów niższego rzędu miejsca docelowego; bity docelowe wyższego rzędu są usuwane. PDEP
robi odwrotnie dla wybranych bitów: sąsiadujące bity niższego rzędu są kopiowane do wybranych bitów miejsca docelowego; inne bity miejsca docelowego są kasowane. Można tego użyć do wyodrębnienia dowolnego pola bitowego z danych wejściowych, a nawet do wykonania wielu tasowań na poziomie bitów, które wcześniej byłyby kosztowne. Podczas gdy to, co robią te instrukcje, jest podobne do instrukcji zbierania-rozpraszania na poziomie bitów SIMD, instrukcje PDEP
i PEXT
(podobnie jak pozostałe zestawy instrukcji BMI) działają na rejestrach ogólnego przeznaczenia.
Instrukcje są dostępne w wersji 32-bitowej i 64-bitowej. Przykład użycia dowolnego źródła i selektora w trybie 32-bitowym to:
Instrukcja | Maska selektora | Źródło | Miejsce docelowe |
---|---|---|---|
PEXT |
0xff00fff0 |
0x12345678 |
0x00012567
|
PDEP |
0xff00fff0 |
0x00012567 |
0x12005670
|
Procesory AMD przed Zen 3, które implementują PDEP i PEXT, robią to w mikrokodzie, z opóźnieniem 18 cykli zamiast (Zen 3) 3 cykli. W rezultacie często szybsze jest użycie innych instrukcji na tych procesorach.
TBM (manipulacja bitem końcowym)
TBM składa się z instrukcji komplementarnych do zestawu instrukcji uruchomionego przez BMI1; ich komplementarny charakter oznacza, że niekoniecznie muszą być używane bezpośrednio, ale mogą być generowane przez kompilator optymalizujący, jeśli jest obsługiwany. AMD wprowadziło TBM wraz z BMI1 w swojej linii procesorów Piledriver ; późniejsze procesory AMD Jaguar i Zen nie obsługują TBM. Żadne procesory Intela (przynajmniej przez Alder Lake ) nie obsługują TBM.
Kodowanie | Instrukcja | Opis | Równoważne wyrażenie C |
---|---|---|---|
XOP.LZ.0A 10 /r ident
|
BEXTR
|
Wyciąg z pola bitowego (z natychmiastowym) |
(źródło >> początek) & ((1 << długość) - 1)
|
XOP.LZ.09 01 /1
|
WYPEŁNIJ
|
Wypełnij od najniższego czystego bitu |
x & (x + 1)
|
XOP.LZ.09 02 /6
|
BLCI
|
Wyizoluj najniższy czysty bit |
x | ~(x + 1)
|
XOP.LZ.09 01 /5
|
BLCIC
|
Wyizoluj najniższy czysty bit i dopełnij |
~x & (x + 1)
|
XOP.LZ.09 02 /1
|
BLCMSK
|
Maska od najniższego czystego bitu |
x ^ (x + 1)
|
XOP.LZ.09 01 /3
|
BLCS
|
Ustaw najniższy czysty bit |
x | (x + 1)
|
XOP.LZ.09 01 /2
|
BLSFILL
|
Wypełnij od najniższego ustawionego bitu |
x | (x-1)
|
XOP.LZ.09 01 /6
|
BLSIC
|
Wyizoluj najniższy ustawiony bit i uzupełnienie |
~x | (x-1)
|
XOP.LZ.09 01 /7
|
T1MSKC
|
Maska odwrócona od tych końcowych |
~x | (x + 1)
|
XOP.LZ.09 01 /4
|
TZMSK
|
Maska od końcowych zer |
~x & (x - 1)
|
Wspieranie procesorów
-
Intel
- Intel Nehalem i nowsze (takie jak Sandy Bridge , Ivy Bridge ) (obsługiwane przez POPCNT)
- Procesory Intel Silvermont (obsługiwane przez POPCNT)
- Intel Haswell i nowsze (takie jak Skylake , Broadwell ) (obsługiwane ABM, BMI1 i BMI2)
-
AMD
- oparte na K10 (obsługiwane przez ABM)
- Procesory o niskim poborze mocy „Cat”.
- oparte na Bobcat (obsługiwane przez ABM)
- oparte na Jaguarze i nowsze (obsługiwane ABM i BMI1)
- oparte na Puma i nowsze (obsługiwane ABM i BMI1)
- Procesory „ciężkiego sprzętu”.
- oparte na spychaczach (obsługiwane przez ABM)
- oparte na Piledriver (obsługiwane ABM, BMI1 i TBM)
- oparte na Steamroller (obsługiwane ABM, BMI1 i TBM)
- oparte na koparkach i nowsze (obsługiwane ABM, BMI1, BMI2 i TBM; mikrokodowane PEXT i PDEP)
- na Zen , Zen+ i Zen 2 (obsługiwane ABM, BMI1 i BMI2; mikrokodowane PEXT i PDEP)
- Zen 3 i nowsze (obsługiwane ABM, BMI1 i BMI2; pełna implementacja sprzętowa)
Należy zauważyć, że obsługa rozszerzeń instrukcji oznacza, że procesor jest w stanie wykonać obsługiwane instrukcje w celu zapewnienia zgodności oprogramowania. W takim przypadku procesor może nie działać dobrze. Na przykład procesory Excavator do Zen 2 implementują instrukcje PEXT i PDEP przy użyciu mikrokodu, co powoduje, że instrukcje są wykonywane znacznie wolniej niż to samo zachowanie odtworzone przy użyciu innych instrukcji. (Metoda oprogramowania o nazwie „zp7” jest w rzeczywistości szybsza na tych komputerach.) W celu uzyskania optymalnej wydajności zaleca się, aby programiści kompilatorów wybierali stosowanie indywidualnych instrukcji w rozszerzeniach na podstawie profili wydajności specyficznych dla architektury, a nie dostępności rozszerzeń.
Zobacz też
- Zaawansowane rozszerzenia wektorowe (AVX)
- Zestaw instrukcji AES
- Zestaw instrukcji CLMUL
- F16C
- Zestaw instrukcji FMA
- Intel ADX
- Zestaw instrukcji XOP
- Kody operacyjne Intel BCD (używane również w zaawansowanych technikach manipulacji bitami)
Dalsza lektura
- Warren Jr., Henry S. (2013). Rozkosz hakera (wyd. 2). Addison Wesley - Pearson Education, Inc. ISBN 978-0-321-84268-8 .