You are on page 1of 33

IDZ DO

PRZYKADOWY ROZDZIA
SPIS TRECI

KATALOG KSIEK
KATALOG ONLINE
ZAMW DRUKOWANY KATALOG

Uczta programistw
Autorzy: Henry S. Warren, Jr.
Tumaczenie: Marek Ptlicki (rozdz. 1 9),
Bartomiej Garbacz (rozdz. 10 16, dod. A, B)
ISBN: 83-7361-220-3
Tytu oryginau: Hacker's Delight
Format: B5, stron: 336

TWJ KOSZYK
DODAJ DO KOSZYKA

CENNIK I INFORMACJE
ZAMW INFORMACJE
O NOWOCIACH
ZAMW CENNIK

CZYTELNIA
FRAGMENTY KSIEK ONLINE

Do tworzenia wydajnych programw nie wystarczy teoretyczna wiedza o algorytmach,


strukturach danych i inynierii oprogramowania. Istnieje pokana liczba sztuczek,
sprytnych technik i praktycznych rozwiza, ktrych znajomo jest niezbdna
kademu programicie.
Niniejsza ksika zawiera pokany zestaw technik, ktre pomog zaoszczdzi sporo
czasu. Techniki te zostay opracowane przez twrcw kodu poszukujcych eleganckich
i wydajnych sposobw tworzenia lepszego oprogramowania. W Uczcie programistw
dowiadczony programista Hank Warren dzieli si z Czytelnikami znanymi sobie
sztuczkami, ktre zgromadzi wraz z imponujcym dowiadczeniem w dziedzinie
programowania aplikacji i systemw operacyjnych. Wikszo z tych sztuczek jest
niezwykle praktyczna, niektre zostay przedstawione jako ciekawostki lub zaskakujce
rozwizania. Ich zestawienie stanowi niesamowit kolekcj, ktra jest w bdzie
pomocna nawet dla najbardziej dowiadczonych programistw w rozszerzeniu ich
umiejtnoci.
W ksice opisano nastpujce zagadnienia:
Obszerna kolekcja uytecznych sztuczek programistycznych
Drobne algorytmy rozwizujce czsto spotykane problemy
Algorytmy kontroli przekroczenia ogranicze
Zmiana kolejnoci bitw i bajtw
Dzielenie cakowite i dzielenie przez stae
Elementarne operacje na liczbach cakowitych
Kod Gray'a
Krzywa Hilberta
Formuy wyznaczania liczb pierwszych

Wydawnictwo Helion
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
e-mail: helion@helion.pl

Niniejsza ksika jest doskona pozycj dla wszystkich programistw, ktrzy maj
zamiar tworzy wydajny kod. Uczta programistw nauczy Ci tworzenia aplikacji
wysokiej jakoci wyszej ni wymagana a uczelniach i kursach programowania.

Spis treci
Przedmowa...........................................................................................................9
Wstp ................................................................................................................11
Rozdzia 1. Wprowadzenie .................................................................................13
1.1. Notacja .......................................................................................................................13
1.2. Zestaw instrukcji i model wykonawczy .....................................................................17

Rozdzia 2. Podstawy ........................................................................................23


2.1. Manipulowanie prawostronnymi bitami ....................................................................23
2.2. czenie dodawania z operacjami logicznymi...........................................................27
2.3. Nierwnoci w wyraeniach logicznych i arytmetycznych .......................................29
2.4. Warto bezwzgldna.................................................................................................30
2.5. Rozszerzenie o znak ...................................................................................................31
2.6. Przesunicie w prawo ze znakiem za pomoc instrukcji przesunicia bez znaku .....32
2.7. Funkcja signum ..........................................................................................................32
2.8. Funkcja porwnania trjwartociowego ....................................................................33
2.9. Przeniesienie znaku ....................................................................................................34
2.10. Dekodowanie pola zero oznacza 2n ......................................................................34
2.11. Predykaty porwna.................................................................................................35
2.12. Wykrywanie przepenienia.......................................................................................40
2.13. Kod warunkowy operacji dodawania, odejmowania i mnoenia.............................49
2.14. Przesunicia cykliczne .............................................................................................50
2.15. Dodawanie i odejmowanie liczb o podwjnej dugoci...........................................51
2.16. Przesunicia liczb o podwjnej dugoci .................................................................52
2.17. Operacje dodawania, odejmowania i wyznaczania wartoci bezwzgldnej
na wartociach wielobajtowych ......................................................................................53
2.18. Doz, Max oraz Min ..................................................................................................54
2.19. Wymiana wartoci midzy rejestrami ......................................................................56
2.20. Wymiana dwch lub wikszej liczby wartoci ........................................................59

Rozdzia 3. Ograniczenia potg dwjki .................................................................63


3.1. Zaokrglanie do wielokrotnoci znanych potg liczby 2 ...........................................63
3.2. Zaokrglanie w gr lub w d do nastpnej potgi liczby 2.....................................64
3.3. Wykrywanie przekroczenia ogranicze potgi dwjki ..............................................67

Rozdzia 4. Ograniczenia arytmetyczne...............................................................71


4.1. Kontrola ogranicze liczb cakowitych......................................................................71
4.2. Ograniczenia zakresw w operacjach sumy i rnicy ...............................................74
4.3. Ograniczenia zakresw w operacjach logicznych......................................................78

Uczta programistw

Rozdzia 5. Zliczanie bitw ................................................................................85


5.1. Zliczanie jedynek .......................................................................................................85
5.2. Parzysto...................................................................................................................94
5.3. Zliczanie zer wiodcych.............................................................................................97
5.4. Zliczanie zer kocowych..........................................................................................104

Rozdzia 6. Przeszukiwanie sw ......................................................................111


6.1 Wyszukiwanie pierwszego bajtu o wartoci 0 ..........................................................111
6.2. Wyszukiwanie pierwszego cigu jedynek o zadanej dugoci.................................117

Rozdzia 7. Manipulacja bitami i bajtami ..........................................................121


7.1. Odwracanie kolejnoci bitw i bajtw .....................................................................121
7.2. Tasowanie bitw ......................................................................................................126
7.3. Transponowanie macierzy bitw .............................................................................128
7.4. Kompresja lub uoglniona ekstrakcja ......................................................................137
7.5. Uoglnione permutacje, operacja typu owce i kozy............................................143
7.6. Zmiana kolejnoci oraz transformacje oparte na indeksach.....................................148

Rozdzia 8. Mnoenie.......................................................................................151
8.1. Mnoenie czynnikw wieloelementowych ..............................................................151
8.2. Bardziej znaczca poowa 64-bitowego iloczynu ....................................................154
8.3. Konwersje midzy bardziej znaczc poow 64-bitowego iloczynu ze znakiem
i bez znaku ....................................................................................................................155
8.4. Mnoenie przez stae................................................................................................156

Rozdzia 9. Dzielenie cakowitoliczbowe ...........................................................161


9.1. Warunki wstpne......................................................................................................161
9.2. Dzielenie wartoci wieloelementowych...................................................................165
9.3. Krtkie dzielenie bez znaku za pomoc dzielenia ze znakiem ................................170
9.4. Dugie dzielenie bez znaku ......................................................................................173

Rozdzia 10. Dzielenie liczb cakowitych przez stae................................................181


10.1. Dzielenie ze znakiem przez znan potg liczby 2 ................................................181
10.2. Reszta ze znakiem z dzielenia przez znan potg liczby 2 ..................................182
10.3. Dzielenie i reszta ze znakiem w przypadku innych wartoci ni potgi liczby 2 ..184
10.4. Dzielenie ze znakiem przez dzielniki 2...............................................................187
10.6. Zawieranie obsugi w kompilatorze .......................................................................197
10.7. Inne zagadnienia.....................................................................................................201
10.8. Dzielenie bez znaku ...............................................................................................205
10.9. Dzielenie bez znaku przez dzielniki 1.................................................................207
10.10. Zawieranie obsugi w kompilatorze .....................................................................210
10.11. Inne zagadnienia (dzielenia bez znaku) ...............................................................212
10.12. Zastosowalno w przypadku dzielenia z moduem i dzielenia z funkcj podoga .. 215
10.13. Podobne metody...................................................................................................215
10.14. Przykadowe liczby magiczne..............................................................................216
10.15. Dzielenie dokadne przez stae.............................................................................217
10.16. Sprawdzanie zerowej reszty po wykonaniu dzielenia przez sta........................225

Rozdzia 11. Niektre funkcje podstawowe ........................................................231


11.1. Cakowitoliczbowy pierwiastek kwadratowy ........................................................231
11.2 Cakowitoliczbowy pierwiastek szecienny............................................................239
11.3. Cakowitoliczbowe podnoszenie do potgi............................................................241
11.4. Logarytm cakowitoliczbowy.................................................................................243

Spis treci

Rozdzia 12. Niezwyke podstawy systemw liczbowych .....................................251


12.1. Podstawa 2............................................................................................................251
12.2. Podstawa 1 + i ......................................................................................................258
12.3. Inne podstawy ........................................................................................................261
12.4. Najbardziej wydajna podstawa...............................................................................262

Rozdzia 13. Kod Graya .....................................................................................263


13.1. Kod Graya ..............................................................................................................263
13.2. Zwikszanie wartoci liczb cakowitych zakodowanych w kodzie Graya ............266
13.3. Ujemno-binarny kod Graya....................................................................................267
13.4. Rys historyczny i zastosowania..............................................................................268

Rozdzia 14. Krzywa Hilberta .............................................................................269


14.1. Rekurencyjny algorytm generowania krzywej Hilberta.........................................271
14.2. Okrelanie wsprzdnych na podstawie odlegoci wzdu krzywej Hilberta .....273
14.3. Okrelanie odlegoci na podstawie wsprzdnych na krzywej Hilberta .............280
14.4. Zwikszanie wartoci wsprzdnych na krzywej Hilberta ...................................282
14.5. Nierekurencyjny algorytm generowania ................................................................285
14.6. Inne krzywe wypeniajce przestrze ....................................................................285
14.7. Zastosowania..........................................................................................................286

Rozdzia 15. Liczby zmiennopozycyjne ................................................................289


15.1. Standard IEEE ........................................................................................................289
15.2. Porwnywanie liczb zmiennopozycyjnych za pomoc operacji
cakowitoliczbowych ....................................................................................................292
15.3. Rozkad cyfr wiodcych.........................................................................................293
15.4. Tabela rnych wartoci.........................................................................................295

Rozdzia 16. Wzory na liczby pierwsze................................................................299


16.1. Wprowadzenie........................................................................................................299
16.2. Wzory Willansa......................................................................................................301
16.3. Wzory Wormella ....................................................................................................305
16.4. Wzory na inne trudne funkcje ................................................................................306

Dodatek A Tablice arytmetyczne dla maszyny 4-bitowej ...................................313


Dodatek B Metoda Newtona ...........................................................................319
Bibliografia.......................................................................................................321
Skorowidz.........................................................................................................325

Rozdzia 7.

Manipulacja
bitami i bajtami
7.1. Odwracanie kolejnoci
bitw i bajtw
Przez operacje odwrcenia kolejnoci bitw (ang. reversing bits) rozumiemy wykonanie
odbicia lustrzanego, na przykad:
rev(0x01234567) = 0xE6A2C480
Przez operacj odwrcenia bajtw rozumiemy podobne odbicie, z tym, e w tym przypadku odwracamy kolejno bajtw w sowie. Odwracanie kolejnoci bajtw jest operacj konieczn w przypadku konwersji pomidzy formatami little-endian, stosowanymi
w procesorach DEC oraz Intel a formatem big-endian, stosowanym przez wikszo pozostaych producentw procesorw.
Odwrcenie kolejnoci bitw moe zosta wykonane w stosunkowo wydajny sposb
przez zamian kolejnoci ssiadujcych bitw, nastpnie zamian kolejnoci w ssiadujcych parach pl 2-bitowych itd. [Aus1]. Poniej przedstawiamy przykad realizacji tego
mechanizmu. Wszystkie operacje przypisania mona wykona w dowolnej kolejnoci.
 
   

   
   
   
 
  


Na wikszoci maszyn jest moliwe dokonanie niewielkiego usprawnienia, polegajcego na wykorzystaniu mniejszej liczby rnych staych oraz na wykonaniu ostatnich dwch
przypisa w bardziej bezporedni sposb, tak jak zostao przedstawione na listingu 7.1
(30 instrukcji z podstawowego zestawu RISC, bez rozgazie).

122

Uczta programistw

Listing 7.1. Odwracanie kolejnoci bitw



 
  

   
   
   
   
 
!

Ostatnie przypisanie zmiennej x w tym kodzie realizuje odwrcenie bajtw w dziewiciu instrukcjach zestawu podstawowego RISC. W przypadku, gdy maszyna udostpnia instrukcje przesuni cyklicznych, mona tego dokona w siedmiu instrukcjach,
wykorzystujc nastpujc formu:
rot

rot

x = (( x & 0x00FF00FF) >> 8) | (( x << 8) & 0x00FF00FF) .


Na procesorach PowerPC operacj odwrcenia bajtw mona wykona w zaledwie trzech
instrukcjach [Hay1]: przesunicie cykliczne w lewo o 8, ktre umieszcza dwa bajty na
odpowiednich miejscach, po ktrym wykonuje si dwa wywoania instrukcji 
(ang. rotate left word immediate then mask insert przesunicie cykliczne w lewo a nastpnie podstawienie wartoci z zastosowaniem maski).

Uoglnienie operacji odwrcenia bitw


W publikacji [GLS1] zasugerowano nastpujcy sposb uoglnienia operacji odwrcenia bitw. Sposb ten nazwano . Bardzo dobrze nadaje si on do zastosowania jako
nowa instrukcja w zestawie instrukcji procesora:
"#
 
   

"#   
"#   
"#   
"#
 
  


Mona pomin ostatnie dwa wywoania instrukcji and. Dla k = 31 operacja ta dokonuje
odwrcenia bitw w sowie. Dla k = 24 odwraca bajty w sowie. Dla k = 7 odwraca
bity w kadym bajcie bez dokonywania zmian pooenia bajtw. Dla k = 16 dokonuje
zamiany psw w sowie itd. Oglnie mwic, operacja ta przenosi bit z pozycji m na
pozycj m k. Instrukcja ta moe zosta zaimplementowana w sprzcie w podobny
sposb, w jaki z reguy s implementowane instrukcje przesunicia cyklicznego (pi
segmentw MUX, z ktrych kady jest kontrolowany za pomoc jednego bitu rozmiaru przesunicia k).

Wariacje na temat odwracania bitw


Pozycja 167 w [HAK] przedstawia do nietypowe wyraenia wykonujce odwracanie 6,
7 i 8-bitowych liczb cakowitych. Wyraenia te s zaprojektowane dla 36-bitowych

Rozdzia 7. Manipulacja bitami i bajtami

123

maszyn, lecz wersja dla wartoci 6-bitowych dziaa rwnie na maszynie 32-bitowej,
natomiast wersje dla liczb 7 i 8-bitowych dziaaj na maszynach 64-bitowych.
6 bitw: remu((x 0x00082082) & 0x01122408, 255)
7 bitw: remu((x 0x40100401) & 0x442211008, 255)
8 bitw: remu((x 0x202020202) & 0x10884422010, 1023)
W wyniku powyszych wyrae powstaje czysta liczba cakowita wyrwnana do
prawej, bez zostawiania adnego niepotrzebnego bardziej znaczcego bitu.
W kadej z tych sytuacji funkcja  moe zosta zastpiona funkcj  lub 
,
poniewa jej argumenty s liczbami dodatnimi. Funkcja  (ang. reminder reszta
z dzielenia) po prostu sumuje cyfry liczby o podstawie 256 lub 1024, co dziaa zupenie tak samo, jak w przypadku metody odrzucania dziewitek (ang. casting out nines).
Dziki temu mona j zastpi za pomoc kombinacji mnoenia i przesuni w prawo.
Na przykad 6-bitowa formua posiada na maszynie 32-bitowej nastpujc posta alternatywn (mnoenie musi by wykonywane modulo 232):
t (x 0x00082082) & 0x01122408
u

( t 0x01010101) >> 24

Przedstawione formuy maj do ograniczone zastosowanie z powodu wykorzystania


operacji reszty z dzielenia (20 cykli lub wicej) oraz kilku dodatkowych mnoe i operacji adowania duych wartoci bezporednich. Ostatnia z powyszych formu wykorzystuje dziesi instrukcji z podstawowego zestawu RISC, z ktrych dwie s instrukcjami
mnoenia, co na wspczesnych procesorach klasy RISC daje w sumie okoo 20 cykli.
Z drugiej strony wykorzystanie kodu z listingu 7.1 w celu odwracania liczb 6-bitowych
wymaga zastosowania okoo 15 instrukcji oraz okoo 9 do 15 cykli, w zalenoci od moliwoci procesora w zakresie rwnolegego wykonania niezalenych instrukcji. Techniki te mona jednak zaimplementowa za pomoc prostego i zwartego kodu. Poniej prezentujemy techniki, ktre mog by przydatne w maszynach 32-bitowych. Wykorzystuj
one co na ksztat podwjnego zastosowania pomysu z [HAK], co posuyo do rozwinicia tej techniki do liczb 8 i 9-bitowych na maszynach 32-bitowych.
Ponisza formua suy do odwracania bitw w 8-bitowej liczbie cakowitej:
s (x 0x02020202) & 0x84422010
t (x 8) & 0x00000420
remu(s + t, 1023)
W tym przypadku funkcji  nie mona zastpi kombinacj mnoenia i przesunicia. Wyjanienie przyczyny pozostawiamy Czytelnikowi. Dla uatwienia proponujemy
przyjrze si ukadowi bitw w staych, wykorzystywanych przez formu.

124

Uczta programistw

Oto podobna formua suca do odwracania bitw w 8-bitowych liczbach cakowitych.


Jest ona ciekawa dlatego, e moemy j dodatkowo nieco uproci:
s (x 0x00020202) & 0x01044010
t (x 0x00080808) & 0x02088020
remu(s + t, 4095)
Uproszczenia polegaj na tym, e drugi iloczyn jest po prostu przesuniciem w lewo
pierwszego iloczynu, natomiast ostatni z zastosowanych staych mona wyliczy z drugiej za pomoc pojedynczej instrukcji przesunicia a operacj wyliczania reszty z dzielenia mona w tym przypadku zastpi kombinacj mnoenia i przesunicia. Dziki temu formu ta upraszcza si do 14 instrukcji z podstawowego zestawu instrukcji RISC,
z ktrych dwie to instrukcje mnoenia:
u x 0x00020202
m 0x01044010
su&m
t (u << 2) & (m << 1)

(0x01001001 (s + t)) >> 24


Formua suca do odwracania bitw w liczbach 9-bitowych jest nastpujca:
s (x 0x01001001) & 0x84108010
t (x 0x00040040) & 0x00841080
remu(s + t, 1023)
Drugie z mnoe mona wyeliminowa, poniewa jego iloczyn jest rwny pierwszemu
iloczynowi przesunitemu o sze miejsc w prawo. Ostatnia staa jest rwna drugiej przesunitej w prawo o osiem pozycji. Wykorzystujc te uproszczenia mona t formu
sprowadzi do postaci wykorzystujcej 12 instrukcji z podstawowego zestawu RISC,
w tym dwa mnoenia i jedn reszt z dzielenia. Operacja wyznaczania reszty musi by
bez znaku i nie mona jej zastpi kombinacj mnoenia i przesunicia.
Czytelnik moe samodzielnie skonstruowa podobny kod dla innych operacji manipulujcych bitami. W charakterze prostego (i sztucznego) przykadu posuymy si operacj wydobycia co drugiego bitu z 8-bitowej wartoci a nastpnie kompresji czterech
wydobytych bitw z wyrwnaniem do prawej. To znaczy mamy zamiar wykona nastpujc operacj:
$%&"'
%"'

Operacj t mona zaimplementowa w nastpujcy sposb:


t (x 0x01010101) & 0x40100401
u

(t 0x08040201) >> 27

Rozdzia 7. Manipulacja bitami i bajtami

125

Na wikszoci maszyn najpraktyczniejszy sposb realizacji tego zadania polega na utworzeniu tablicy przegldowej wszystkich wartoci (na przykad jednobajtowych lub 9-bitowych).

Zwikszanie wartoci odwrconej liczby cakowitej


Algorytm szybkiego przeksztacenia Fouriera (ang. Fast Fourier Transform FFT)
wymaga zastosowania liczby cakowitej i oraz jej odwrconej wersji rev(i) w ptli, w ktrej warto i jest za kadym razem zwikszana o 1 [PB]. W najprostszym rozwizaniu
w kadej iteracji wyliczalibymy now warto liczby i a nastpnie wyliczalibymy rev(i).
Dla niewielkich liczb cakowitych zastosowanie tablicy przegldowej jest proste i praktyczne. Dla duych wartoci i technika taka nie jest praktyczna, a jak ju wiemy wyliczenie rev(i) wymaga 29 instrukcji.
Jeli jest wykluczone zastosowanie tablicy przegldowej, bardziej wydajne byoby osobne przechowywanie wartoci i oraz rev(i), w kadej iteracji zwikszajc obydwie te
wartoci. W tym momencie pojawia si problem zwikszenia liczby, ktrej warto posiadamy w odwrconej formie. W celu ilustracji prezentujemy zastosowanie tej techniki
na maszynie 4-bitowej w postaci kolejnych wartoci w notacji szesnastkowej:
((((( (()(
(*((+((,(-(.

W algorytmie FFT zarwno liczba, i jak jej odwrcona wersja stanowi okrelon liczb bitw o okrelonej dugoci, ktra nigdy nie przekracza 32 i obydwie s wyrwnane do prawej w ramach rejestru. Zamy, e i jest 32-bitow liczb cakowit. Po zwikszeniu o 1 jej odwrconej wartoci przesunicie w prawo o odpowiedni liczb bitw
spowoduje, e liczba wynikowa stanie si waciw wartoci w algorytmie FFT (zarwno i, jak i rev(i) s wykorzystywane jako indeksy w tablicy).
Najprostszym sposb zwikszenia wartoci odwrconej liczby cakowitej jest wyszukanie lewostronnego zera, zmiana jego wartoci na 1 a nastpnie ustawienie wszystkich
bitw na lewo od tego miejsca na 0. Jeden ze sposobw realizacji tego algorytmu prezentuje nastpujcy listing:
(/
/
0/
"  
1
// 

0/
!2'3 /
!

W przypadku, gdy pierwszy bit od lewej ma warto 0, powyszy kod wykonuje si


w trzech instrukcjach z podstawowego zestawu RISC i w kadej iteracji s wykorzystywane cztery kolejne instrukcje. Warto rozpoczyna si bitem 0 w poowie przypadkw, sekwencj 10 w jeden czwartej przypadkw i tak dalej, zatem rednia liczba instrukcji wykorzystywanych przez ten algorytm wynosi w przyblieniu:

126

Uczta programistw

1
1
1
1
3 + 7 + 11 + 15 + K
2
4
8
16
1
1
1
1
= 4 + 8 + 12 + 16 + K 1
4
8
16
2
1 2 3 4

= 4 + + + + K 1
2 4 8 16

= 7.

W drugim wierszu powyszych oblicze dodalimy i odjlimy 1, pierwsza z tych jedynek zostaa rozpisana jako 1/2 + 1/4 + 1/8 + 1/16 + . Pod tym wzgldem obliczenia te s podobne do przedstawionych na stronie 107). W najgorszym przypadku powyszy algorytm wymaga wykonania do duej liczby instrukcji, bo a 131.
W przypadku, gdy dostpna jest instrukcja wyliczajca liczb zer wiodcych, zwikszenie o 1 wartoci odwrconej liczby cakowitej mona zrealizowa w nastpujcy sposb:
Najpierw wyliczamy s nlz(x)

nastpnie: x x (0x80000000 >> s)

lub: x ((x << s) + 0x80000000) >> s


Kady ze sposobw wykorzystuje pi instrukcji z penego zestawu RISC a dodatkowo wymagane jest, aby przesunicia byy wykonywane modulo 64, w celu obsuenia
przypadku, gdy nastpuje zawinicie wartoci 0xFFFFFFFF do 0 (dlatego powysze
formuy nie bd dziaa na maszynach z rodziny Intel x86, poniewa w tych procesorach przesunicia s wykonywane modulo 32).

7.2. Tasowanie bitw


Kolejnym wanym sposobem manipulowania bitami jest operacja tasowania zupenego (ang. perfect shuffle), wykorzystywana w kryptografii. Istniej dwie odmiany tej
operacji, znane jako wewntrzna (ang. inner) oraz zewntrzna (ang. outer). Obydwie
w wyniku daj uoone naprzemiennie bity z dwch powek sowa w sposb przypominajcy dokadne potasowanie dwch powek talii zoonej z 32 kart. Rnica pomidzy tymi dwoma odmianami polega na tym, z ktrej czci talii pobieramy pierwsz
kart. W tasowaniu zewntrznym zewntrzne bity pozostaj na pozycjach zewntrznych,
w odmianie wewntrznej bit na pozycji 15 przesuwa si na lew stron wyniku (pozycj 31). Zamy, e nasze sowo skada si z bitw oznaczonych w nastpujcy sposb:
$%&"'4#3/15 ,+)6789:;<=>?

W wyniku tasowania zewntrznego uzyskamy nastpujce sowo:


$ %,&+)"6'7849#:3;/<=1>5?

Rozdzia 7. Manipulacja bitami i bajtami

127

W wyniku tasowania wewntrznego uzyskamy nastpujcy wynik:


$,%&+)"67'894:#;3</=>1?5

Zamy, e rozmiar sowa W jest potg liczby dwa. W tym przypadku operacj tasowania zupenego mona wykona za pomoc instrukcji podstawowego zestawu RISC
w log2(W/2) krokw. Kady z krokw skada si z zamiany kolejnoci drugiej i trzeciej
wiartki coraz mniejszego fragmentu sowa. Ilustruje to nastpujcy przykad:
$%&"'4#3/15 ,+)6789:;<=>?
$%&"' ,+)674#3/1589:;<=>?
$%& ,+"')674#389:;/15<=>?
$% ,&+")'67489#3:;/<=15>?
$ %,&+)"6'7849#:3;/<=1>5?

Oto najprostszy sposb realizacji tego zadania:


    
    
    
 
  
 ********

Powyszy sposb wymaga zastosowania 42 instrukcji z podstawowego zestawu instrukcji RISC. Liczb t mona zredukowa do 30 lecz kosztem zwikszenia liczby
instrukcji w przypadku procesorw o nieograniczonej liczbie jednoczenie wykonywanych, niezalenych instrukcji. W tym celu wykorzystujemy instrukcj rnicy symetrycznej w celu wymiany ssiadujcych pl w rejestrze (opisywanej na stronie 57). W poniszym kodzie wszystkie wartoci s liczbami bez znaku:





0 0
0 0
0 0
0 
0

0
0
0
0

 
 
 
 


Operacja odwrotna, zewntrzne odtasowanie (ang. outer unshuffle), moe zosta zrealizowana za pomoc odwrcenia kolejnoci operacji w powyszym kodzie:





0 
0
0 0
0 0
0 0

0
0
0
0

 

 
 
 

Wykorzystanie dwch ostatnich krokw z dowolnego z powyszych algorytmw tasowania spowoduje potasowanie kadego z bajtw osobno. Wykorzystanie ostatnich trzech
krokw spowoduje potasowanie kadego z psw osobno itd. Podobne uwagi dotycz
operacji odtasowania, z t rnic, e kroki liczymy od pocztku.
W celu uzyskania wewntrznego tasowania zupenego (ang. inner perfect shuffle) na
pocztku kadego z powyszych sposobw naley doda nastpujce wyraenie, zamieniajce stronami powki sowa:
 
  


128

Uczta programistw

Mona rwnie zastosowa przesunicie cykliczne o 16 pozycji. Operacj odtasowania


mona zrealizowa za pomoc zakoczenia procedury tym samym wyraeniem.
Efektem zmodyfikowania algorytmu w ten sposb, e zamiana miejscami bdzie dotyczya pierwszej i czwartej wiartki kolejno pomniejszanych pl, jest sowo bdce odwrceniem wewntrznego tasowania zupenego.
Warto wspomnie o przypadku szczeglnym, gdy lewa powka sowa ma wszystkie
bity o wartoci 0. Innymi sowy, chcemy przenie bity prawej powki do co drugiego
bitu, przeksztacajc sowo o nastpujcej strukturze:
 ,+)6789:;<=>?

W wyniku uzyskamy nastpujce sowo:


 ,+)6789:;<=>?

Algorytm zewntrznego tasowania zupenego mona zmodyfikowa w taki sposb,


aby to zadanie byo realizowane w 22 instrukcjach podstawowego zestawu RISC. Poniszy kod wykonuje to zadanie w 19 instrukcjach bez dodatkowego kosztu, w przypadku wykonywania go na maszynach o nieograniczonych moliwociach jednoczesnego
wykonania niezalenych instrukcji (12 cykli w przypadku kadej z metod). Metoda ta nie
wymaga, aby zawarto bardziej znaczcej powki sowa bya wstpnie wyczyszczona.
  
  
  
 
 

Istnieje take moliwo skonstruowania podobnej do metody tasowania powkowego metody odwrcenia tego przypadku tasowania (bdc szczeglnym przypadkiem
operacji kompresji, omwionej na stronie 137). Metoda ta wymaga od 26 do 29 instrukcji podstawowego zestawu RISC, w zalenoci od tego, czy wymagane jest wstpne wyczyszczenie bitw na nieparzystych pozycjach. Poniszy kod wymaga jednak
od 18 do 21 instrukcji z podstawowego zestawu RISC, natomiast w przypadku maszyny
obsugujcej rwnolege wykonanie niezalenych instrukcji kod ten moe zosta wykonany w 12 do 15 cyklach procesora.
@@4A3#1&B
 
 
  
  
  

7.3. Transponowanie macierzy bitw


Transpozycja macierzy A to taka macierz, ktra powstaje w wyniku przestawienia wierszy macierzy A w miejsce kolumn z zachowaniem ich kolejnoci. W tym podrozdziale
zajmiemy si transpozycj macierzy bitw. Elementy omawianej macierzy s zgrupowane

Rozdzia 7. Manipulacja bitami i bajtami

129

w bajty. Wiersze i kolumny tej macierzy rozpoczynaj si na granicy bajtu. Taka pozornie prosta operacja, jak jest transpozycja tego typu macierzy jest bardzo kosztowna
pod wzgldem liczby wykorzystywanych instrukcji.
Na wikszoci maszyn adowanie i przechowywanie pojedynczych bitw byoby bardzo powolne, gwnie z powodu kodu, wymaganego w celu wyodrbnienia i (co gorsza)
przechowywania pojedynczych bitw. Lepszy sposb polega na podzieleniu macierzy
na podmacierze o rozmiarach 88 bitw. Kad z takich macierzy 88 bitw adujemy
do rejestrw, wyliczamy transpozycj podmacierzy a nastpnie macierz wynikow 88
zapisujemy w odpowiednim miejscu macierzy wynikowej.
W niniejszym podrozdziale w pierwszej kolejnoci zajmiemy si problemem wyznaczania transpozycji macierzy 88 bitw.
Sposb przechowywania tablicy, to znaczy kolejno wiersze-kolumny (ang. row-major)
lub kolumny-wiersze (ang. column-major) nie ma znaczenia. Wyznaczenie macierzy
transponowanej w kadym z tych przypadkw wymaga takich samych operacji. Dla
celw dalszych rozwaa przyjmijmy stosowanie kolejnoci wiersze-kolumny, w przypadku ktrej podmacierz 88 jest adowana do omiu rejestrw za pomoc omiu instrukcji adowania wartoci z pamici. Oznacza to, e adresy kolejnych instrukcji adowania
bajtw rni si o wielokrotno szerokoci oryginalnej macierzy liczonej w bajtach. Po
wykonaniu transpozycji podmacierz 88 zostaje umieszczona w kolumnie macierzy
docelowej. Podmacierz ta jest zapisywana za pomoc czterech instrukcji zapisu bajtu
w pamici, z adresami poszczeglnych bajtw rnicymi si od siebie o wielokrotno
szerokoci w bajtach tabeli docelowej (ktra bdzie rna od szerokoci w bajtach tabeli
rdowej, jeli ta nie bya kwadratowa). Zamy zatem, e mamy osiem 8-bitowych
wartoci, wyrwnanych do prawej w rejestrach , , . Chcemy wyliczy osiem
8-bitowych wartoci, wyrwnanych do prawej w rejestrach , , , ktre bd
wykorzystane w instrukcjach zapisu bajtw w pamici. Sytuacje t ilustrujemy poniej, kady z bitw oznaczajc inn cyfr lub liter. Warto zwrci uwag na fakt, e
gwna przektna przebiega od bitu 7. bajtu 0 do bitu 0. bajtu 7. Czytelnicy przywykli do
notacji big-endian mogliby oczekiwa, e gwna przektna przebiega od bitu 0. bajtu 0
do bitu 7. bajtu 7.





  

  !"#

 $%&

 '()*+


',- . ==> $/012
 (/3456

%,3789

!)07:;<

 -4:=>

"*18=?@

 5;?A

#+29>AB

&.6<@B

130

Uczta programistw

Najprostszy kod wykonujcy to zadanie obrabiaby kady bit indywidualnie w sposb


przedstawiony poniej. Mnoenia i dzielenia reprezentuj, odpowiednio, przesunicia
w prawo lub w lewo.
%$
 $

@ $
@ $
@
$
@
 $
@ $
@ $-@

%
$C $
 $@ $@
$@ $@
 $@ $-@
%$C $
C $ $@
$@ $@ $@
 $-@
%$
C $

C $
C $

$
@ $
@ $
@ $-
@

%$C
 $
C $C $C
$ $@ $@ $-@
%$C $
C
 $C $C
$C $ $@ $-@
%$C $
C $C
 $C
$C $C $ $-@
%-$C
 $

C $
C $
C

$
C $
C $
C $-


Powyszy kod na wikszoci maszyn wymaga 174 instrukcji (62 koniunkcje, 56 przesuni oraz 56 alternatyw). Instrukcje alternatywy mona oczywicie zastpi instrukcjami dodawania. Na procesorach PowerPC kod ten moe zosta wykonany w 63 instrukcjach, co moe by do zaskakujce (siedem instrukcji przeniesienia wartoci i 56
instrukcji przesunicia cyklicznego w lewo z nastpujcym podstawieniem wartoci z zastosowaniem maski). Nie liczymy instrukcji adowania i zapisywania wartoci bajtw
ani kodu niezbdnego do wyliczenia ich adresw.
Nie jest powszechnie znany aden algorytm, ktry rozwizywa by ten problem i ktry
mona by uzna za doskonay. Mimo to kolejna z omawianych technik jest dwukrotnie
lepsza od powyszej, w kadym razie w przypadku procesorw obsugujcych instrukcje podstawowego zestawu RISC.
W pierwszej kolejnoci naley potraktowa macierz 88 jako 16 macierzy 22 i wykona transpozycje kadej z tych macierzy 22. Nastpnie ca macierz 88 traktujemy
jak cztery macierze 22, z ktrych kada zawiera macierze 22 z poprzedniego kroku
i ponownie wykonujemy transpozycj. Na kocu ca macierz traktujemy jako macierz 22 skadajc si z macierzy z poprzedniego kroku i wykonujemy transpozycj
tej macierzy. Odpowiednie przeksztacenia bd miay nastpujcy przebieg:


 


%,




  

 

  -

  !"#

 $%&


'%,

 '

 '()*+

',- . ==>

$-&. ==> $&. ==> $/012

 (/3456

()375;

3789

%,3789

!)07:;<

!/04:6<

!&#4:=>

 -4:=>

"*18=?@

*+89?A

()*+5;?A

 5;?A

#+29>AB

"#12=>@B

/0126<@B

&.6<@B

Rozdzia 7. Manipulacja bitami i bajtami

131

Zamiast wykonywa opisane kroki na omiu niezalenych bajtach w omiu rejestrach,


gwne usprawnienie wykorzystuje moliwo spakowania wspomnianych bajtw po
cztery do jednego rejestru, nastpnie mona wykona wymian bitw na powstaych
w ten sposb dwch rejestrach a nastpnie rozpakowa wynik. Kompletna procedura
zostaa zaprezentowana na listingu 7.2. Parametr 3 okrela adres pierwszego bajtu podmacierzy 88 macierzy rdowej o wymiarach 88& bitw. Podobnie parametr 4 stanowi adres pierwszego bajtu podmacierzy 88 macierzy docelowej o wymiarach 8&8
bitw. Oznacza to, e caa macierz rdowa ma wymiary 8& bajtw, natomiast macierz wyjciowa ma wymiary 8& bajtw.
Listing 7.2. Transponowanie macierzy 88 bitw
1 $51&'$ DE( /( (
&'$,DE
(F( 
@@G$4/F $%3&H/B&B$/F4I21$BF
 DE   D/E
  DC/E   DC/E
F DC/E   DC/E
  DC/E   D-C/E
 0 -  0 0  -
 F0F -  FF0 0  -
 0
0 0 

 F0F
FF0 0 

  F 
F  F
 
,DE ,DE
,DCE ,DCE
,DCEF ,DCEF
,DCEF ,D-CEF
!

Z ca pewnoci mao zrozumiay moe wyda si nastpujcy wiersz kodu:


 0 -  0 0  -

Jego zadaniem jest zamiana miejscami w sowie bitw 1. i 8. (liczc od prawej), 3. i 10.,
5. i 12. itd., nie naruszajc zawartoci bitw 0., 2., 4. itd. Zamiana bitw miejscami
jest realizowana za pomoc metody wykorzystujcej rnic symetryczn, opisanej na
stronie 56. Zawarto sowa przed i po pierwszej zamianie wyglda nastpujco:

-*$%&"'4#3/15J 
$&
*%-"1J#/'543 

W celu uzyskania realistycznego porwnania opisanych metod, naiwn metod ze


strony 129 zastosowano w programie podobnym do przedstawionego na listingu 7.2.
Obydwie procedury skompilowano za pomoc kompilatora GNU C na maszynie o parametrach bardzo przypominajcych parametry podstawowego zestawu instrukcji RISC.
W wyniku uzyskano kod skadajcy si z 219 instrukcji dla metody naiwnej (liczc

132

Uczta programistw

instrukcje adowania, zapisu, adresowania oraz instrukcje przygotowujce oraz koczce procedur) oraz 101 instrukcji dla kodu z listingu 7.2 (instrukcje wstpne i koczce nie wystpoway, za wyjtkiem instrukcji powrotu z rozgazienia). Adaptacja kodu
z listingu 7.2 do 64-bitowej wersji standardowego zestawu RISC (w ktrej i ( byyby zapisane w tym samym rejestrze) wykona si w 85 instrukcjach.
Algorytm z listingu 7.2 wykonuje przetwarzanie od najwikszego do najmniejszego rozdrobnienia (biorc pod uwag wielko grup bitw zamienianych miejscami). Metod
t mona rwnie zmodyfikowa w taki sposb, aby wykonywaa przetwarzanie od najmniejszego do najwikszego rozdrobnienia. W tym celu traktujemy macierz 88 bitw
jako macierz 22, skadajc si z macierzy 44 bity i wykonujemy transpozycj tej
macierzy. Nastpnie kad z macierzy 44 traktujemy jako macierze 22 zoone z macierzy 22 bity i wykonujemy transpozycje tych macierzy itd. Kod wynikowy takiego
algorytmu bdzie taki sam, jak na listingu 7.2 za wyjtkiem trzech grup wyrae modyfikujcych kolejno bitw, ktre wystpi w odwrconej kolejnoci.

Transponowanie macierzy o wymiarach 3232 bity


Podobna technika do zastosowanej w przypadku macierzy 88 moe by oczywicie zastosowana dla macierzy o wikszych rozmiarach. Na przykad w przypadku macierzy
3232 metoda ta wymaga zastosowania piciu krokw.
Szczegy implementacji rni si jednak w stosunku do kodu przedstawionego na listingu 7.2, poniewa zakadamy, e caa macierz 3232 nie mieci si w dostpnej przestrzeni rejestrw. Dlatego naley znale zwarty sposb indeksowania odpowiednich
sw macierzy bitowej, za pomoc ktrego bdzie moliwe przeprowadzenie odpowiednich operacji na bitach. Poniszy algorytm dziaa najlepiej w przypadku techniki od
najmniejszego do najwikszego rozdrobnienia.
W pierwszym etapie traktujemy macierz jako cztery macierze 1616 bitw i dokonujemy ich transpozycji w nastpujcy sposb:

A B
A C
C D B D

A oznacza lew powk pierwszych 16 sw macierzy, B oznacza praw powk pierwszych 16 sw macierzy itd. Powysza transformacja moe zosta zrealizowana za pomoc nastpujcych zamian:
Prawa powka sowa 0 z lew powk sowa 16,
Prawa powka sowa 1 z lew powk sowa 17,

Prawa powka sowa 15 z lew powk sowa 31,

Rozdzia 7. Manipulacja bitami i bajtami

133

W celu implementacji tego mechanizmu posuymy si indeksem k o wartociach od 0


do 15. W ptli kontrolowanej wartoci k, prawa powka sowa k zostanie lew powk sowa k + 16.
W drugiej fazie macierz jest traktowana jako 16 macierzy 88 bitw, na ktrej przeprowadzamy nastpujce przeksztacenie:

A
E

B C D A
F G H B

J K L I

N O P J

E C G
F D H
M K O

N L P

Transformacj t mona zrealizowa za pomoc nastpujcych przeksztace:


Bity 0x00FF00FF sowa 0 zamieniamy z bitami 0xFF00FF00 sowa 8
Bity 0x00FF00FF sowa 1 zamieniamy z bitami 0xFF00FF00 sowa 9, itd.
Oznacza to, e bity 0 7 (osiem najmniej znaczcych bitw) sowa 0 zamieniamy z bitami 8 15 sowa 8 itd. Indeksy pierwszego sowa w tych zamianach to k = 0, 1, 2, 3,
4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23. Sposobem na przejcie zmiennej k przez wymienione wartoci jest nastpujce wyraenie:
k = (k + 9) & 8
W ptli kontrolowanej wartoci zmiennej k bity sowa o indeksie k s zamieniane z bitami sowa o indeksie k + 8.
Podobnie trzecia faza wykonuje nastpujce zamiany:
Bity 0x0F0F0F0F sowa 0 zamieniamy z bitami 0xF0F0F0F0 sowa 4,
Bity 0x0F0F0F0F sowa 1 zamieniamy z bitami 0xF0F0F0F0 sowa 5, itd.
Indeksy pierwszego sowa w tych zamianach to k = 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19,
24, 25, 26, 27. Sposobem na przejcie zmiennej k przez wymienione wartoci jest nastpujce wyraenie:
k = (k + 5) & 4
W ptli kontrolowanej wartoci zmiennej k, bity sowa o indeksie k s zamieniane z bitami sowa o indeksie k + 4.
Wynik powyszych rozwaa mona zakodowa w jzyku C w do zwarty sposb,
przedstawiony na listingu 7.3.[GLS1]. Zewntrzna ptla kontroluje pi etapw przetwarzania, zmienna $ przyjmuje wartoci 16, 8, 4, 2 oraz 1. Ptla ta rwnie kontroluje zmian maski o wartociach odpowiednio dla kadego przebiegu: 0x0000FFFF,
0x00FF00FF, 0x0F0F0F0F, 0x33333333 oraz 0x55555555 (kod generujcy mask to
CDEE$F). Algorytm ten nie posiada wersji odwracajcej operacj, jest to jeden z gwnych powodw najlepszego funkcjonowania przeksztace od najmniejszego

134

Uczta programistw

do najwikszego rozdrobnienia macierzy. Wewntrzna ptla jest kontrolowana wartoci zmiennej %, ktra przyjmuje kolejno wartoci wymienione wyej. Wewntrzna ptla powoduje wymian bitw G%H okrelonych mask  z bitami G%I$H przesunitymi
w prawo o $ i rwnie okrelonymi mask , co odpowiada bitom G%I$H okrelonym dopenieniem maski . Kod wykonujcy wspomniane zamiany bitw jest adaptacj
techniki wykorzystujcej trzy rnice symetryczne przedstawionej w podrozdziale Wymiana wartoci midzy rejestrami na stronie 56 w kolumnie (c).
Listing 7.3. Transpozycja macierzy o wymiarach 3232 bity
1 $51 DE
 4(#
/( 
/
"14
4K44 
(//0/ 4
"1## ##L4L
M4
  D#E0 D#L4E 4/
 D#E D#E0 
 D#L4E D#L4E0  4
!
!
!

Po skompilowaniu tej funkcji za pomoc kompilatora GNU C na maszynie o waciwociach zblionych do podstawowego zestawu instrukcji RISC kod ten zawiera 31
instrukcji, 20 w wewntrznej ptli i 7 w zewntrznej. Funkcja ta wykonuje si zatem
w 4 + 5(7 + 16 20) = 1639 instrukcjach. Dla porwnania: gdyby funkcje t wywoano z wykorzystaniem 16 wywoa programu z listingu 7.2, wykonujcego transpozycj macierzy 88, zajoby to 16(101 + 5) = 1696 instrukcji, z zaoeniem, e te 16 wywoa zostaoby wykonanych jedno po drugim.
Obliczenia te obejmuj rwnie pi instrukcji niezbdnych do wykonania wywoania
funkcji (wasno zaobserwowana w skompilowanym kodzie). Std wynika, e obydwie
opisane funkcje s bardzo zblione pod wzgldem czasu wykonania.
Z drugiej strony dla maszyn 64-bitowych kod z listingu 7.3 mona z atwoci zmodyfikowa w taki sposb, e wykonuje transpozycj macierzy 6464 bity w okoo 4 + 6
(7 + 32 20) = 3886 instrukcjach. Realizacja tego celu za pomoc 64 wywoa transpozycji macierzy 88 wymagaoby okoo 64(85 + 5) = 5760 instrukcji.
Algorytm ten wykonuje si w miejscu (na oryginalnej macierzy), dlatego w przypadku transpozycji wikszych macierzy wymaga si dodatkowego kopiowania podmacierzy 3232-bitowych. Algorytm ten mona zmusi do dokonywania zapisu w osobnym obszarze pamici. W tym celu naley wyodrbni pierwszy lub ostatni krok ptli

$i wynik w tym kroku zapisa w osobnym obszarze pamici1.
1

Jeli zrobimy to w pierwszym kroku, unikniemy nadpisania oryginalnej zawartoci macierzy rdowej
przyp. tum.

Rozdzia 7. Manipulacja bitami i bajtami

135

Okoo poow instrukcji definiujcych funkcj na listingu 7.3 stanowi instrukcje kontrolne ptli oraz funkcje odczytujce i zapisujce piciokrotnie ca macierz. Czy rozsdne byoby zmniejszenie tego nakadu za pomoc rozwinicia ptli? Byoby w przypadku, gdyby programicie zaleao na jak najwikszej prdkoci wykonania i gdyby
zwikszona objto kodu nie stanowia problemu. Wanym te jest, aby mechanizm
pobierania instrukcji (ang. I-fetching) w procesorze poradzi sobie z pynnym wykonywaniem tak dugiego bloku nierozgazionego kodu. Przede wszystkim jednak mechanizm ten byby warty rozwaenia, jeli rozgazienia i procedury adowania i zapisu
danych z i do pamici byyby kosztownymi operacjami pod wzgldem czasu wykonywania. Wikszo programu bdzie stanowio sze wierszy wykonujcych zamian
bitw, powtrzone 16 razy (co w wyniku da 80 wierszy). Dodatkowo program bdzie
potrzebowa 32 instrukcji adowania danych, pobierajcych macierz rdow oraz 32 instrukcje zapisu danych, zapisujce macierz wynikow. Wszystko to da w wyniku 544 instrukcje.
Nasz kompilator GNU C nie rozwija ptli w tak duej liczbie przebiegw (15 w wewntrznej ptli, 5 w zewntrznej). Listing 7.4 przedstawia wersj funkcji, w ktrej rozwini dokonano rcznie. Program ten prezentujemy w wersji niepracujcej w miejscu, jednak w razie koniecznoci bdzie on poprawnie dziaa w takiej wersji. W tym
celu funkcj naley wywoa z obydwoma identycznymi argumentami. W programie
wystpuje 80 wierszy wywoujcych makro , . Nasz kompilator GNU C kompiluje
ten kod na maszyn obsugujc podstawowy zestaw instrukcji RISC z wykorzystaniem 576 instrukcji (bez rozgazie, za wyjtkiem powrotu z funkcji), wliczajc w to
czynnoci przygotowawcze i koczce procedur. Wykorzystana maszyna nie obsuguje
instrukcji adowania ani zapisu wielu wartoci (ang. load multiple oraz store multiple),
lecz potrafi zapisa i odczyta warto dwch rejestrw na raz, z wykorzystaniem instrukcji store double oraz load double (zapis oraz odczyt podwjnej wartoci).
Listing 7.4. Transpozycja macierzy o rozmiarze 32x32 bitw w postaci rozwinitej
N"2$5$($
(4(/ $0$
 4/O
$$0 O
$
$
0  4
1 $51 DE(,DE
/( 
$($
($($($($($($-(
$($*($
($

($
($
($
($
(
$
($
-($
($
*($($
($($(
$($($($-($($*($($

$ DE$
 D
E$ DE$ DE
$ DE$ DE$ DE$- D-E
...
$ DE$* D*E$ DE$
 D
E
/
2$5$($
(
(/
2$5$
($
-(
(/
...

136

Uczta programistw

2$5$
($
(
(/
/
2$5$($((/
2$5$
($*((/
...
...
2$5$($*(
(/
2$5$($
(
(/
,DE$,D
E$
,DE$,DE$
,DE$,DE$,DE$,D-E$-
...
,DE$,D*E$*,DE$,D
E$

!

Istnieje sposb na dalsze zwikszenie wydajnoci, o ile maszyna obsuguje instrukcje


przesunicia cyklicznego (w lewo lub w prawo, bez rnicy). Pomys polega na zastpienie wszystkich wywoa makra ,  na listingu 7.4 (z ktrych kade wykorzystuje sze
instrukcji) prostsz form zamiany, niewykorzystujc przesuni i wykorzystujc tylko cztery instrukcje (w istniejcym makrze ,  naley usun operacje przesuni).
Najpierw naley przesun cyklicznie o 16 pozycji w prawo sowa A[16..31] (to znaczy
A[k], gdzie 16 k 31). Nastpnie naley zamieni miejscami prawe powki sw
A[0] z A[16], A[1] z A[17] itd., jak to przedstawiono na listingu 7.4. Nastpnie naley
obrci o osiem pozycji w prawo sowa A[0..8] oraz A[24..31] i zamieni miejscami
bity oznaczone w masce 0x00FF00FF w sowach A[0] z A[8], A[1] z A[9] itd., jak to
przedstawiono na listingu 7.4. Po piciu etapach takich zamian transpozycja nie bdzie
jeszcze wykonana. Naley na kocu przesun cyklicznie A[1] w lewo o jedn pozycj, A[2] o dwie pozycje itd. (31 instrukcji). Nie prezentujemy kompletnego kodu, natomiast przedstawiamy przykad dziaania dla macierzy 44.





==> 

$

$





==> & ==> & ==> &$ ==> $&

$%

%$

%

%

%


%

&


&









Fragment programu na listingu 7.4 odpowiedzialny za manipulacj bitami wykorzystuje


480 instrukcji (80 zamian po sze instrukcji kada). Zmodyfikowany program wykorzystujcy instrukcj przesunicia cyklicznego wykorzystuje 80 zamian po cztery instrukcje
kada, plus 80 instrukcji przesunicia cyklicznego (16 5) w piciu etapach plus kocowe 31 instrukcji przesunicia cyklicznego, co w sumie daje 431 instrukcji. Kod przygotowujcy oraz koczcy funkcj nie ulegnie zmianie, zatem wykorzystanie przesuni
cyklicznych pozwala na zaoszczdzenie 49 instrukcji.
Istnieje inny sposb realizacji transpozycji macierzy, wykorzystujcy trzy przeksztacenia poprzeczne (ang. shearing transformation) [GLS1]. W przypadku, gdy macierz ma
wymiary nn wykorzystywane s nastpujce etapy:

Rozdzia 7. Manipulacja bitami i bajtami

137

 przesunicie cykliczne wiersza i w prawo o i bitw;


 przesunicie cykliczne kolumny j w gr o (j + 1) mod n bitw;
 przesunicie cykliczne wiersza i w prawo o (i + 1) mod n bitw;
 pionowe odbicie macierzy wzgldem rodka.

W celu ilustracji tej techniki przedstawiamy jej zastosowanie na macierzy 44:













==>  ==> %


 ==> %
==> $&

$%

%$

&$

$&

%

&


&








Metoda ta nie stanowi konkurencji dla pozostaych z powodu duej kosztownoci kroku 2.
Aby wykona ten krok w rozsdnej liczbie operacji, naleaoby wykona przesunicie
cykliczne o n/2 pozycji wszystkich kolumn, ktre wykonuj przesunicie o n/2 lub
wiksz liczb pozycji (s to kolumny od n/2 1 do n 2] a nastpnie wykona przesunicie cykliczne odpowiednich kolumn o n/4 pozycji w gr itd. Kroki 1. oraz 3. wymagaj tylko n 1 instrukcji, natomiast krok 4. nie wymaga adnych instrukcji, jeli
wyniki s od razu zapisywane do odpowiednich obszarw w pamici.
W przypadku macierzy 88 zapisanej w pojedynczym sowie 64-bitowym w oczywisty
sposb (to znaczy grny wiersz macierzy jest zapisany w najbardziej znaczcych omiu
bitach rejestru) operacja transpozycji jest rwnowana trzem operacjom zewntrznego
tasowania zupenego i odtasowania [GLS1]. Jest to doskonay sposb realizacji tego zadania, o ile maszyna udostpnia instrukcj tasowania, lecz w przypadku maszyny ze
standardowym zestawem instrukcji RISC nie jest to dobre rozwizanie.

7.4. Kompresja
lub uoglniona ekstrakcja
Jzyk programowania APL posiada operacj kompresji (ang. compress) zapisywan B/V,
gdzie B jest wektorem bitw, natomiast V jest wektorem o tej samej dugoci co B,
zawierajcym dowolne elementy. Wynikiem operacji jest wektor skadajcy si z elementw V, dla ktrych odpowiadajce im bity wektora B maj warto 1. Dugo wektora wynikowego jest rwna liczbie jedynek w B.
W niniejszym podrozdziale zajmiemy si podobn operacj na bitach w sowie. Po podaniu maski m i sowa x, bity w x, dla ktrych odpowiednie bity w masce m maj warto 1 zostaj skopiowane do wyniku i przesunite (skompresowane) do prawej. Zamy na przykad, e operujemy na sowie x o nastpujcej strukturze:
$%&"'4#3/15J FB ,+)

138

Uczta programistw

Maska w naszej operacji bdzie nastpujca:

















W takim przypadku wynikiem operacji 


,, bdzie nastpujce sowo:
"'#315J2B,+

Operacj t mona rwnie nazwa uoglnion ekstrakcj (ang. generalized extract),


przez analogi do instrukcji  - - udostpnianej przez wiele komputerw.
Interesuje nas kod wykonujcy te operacje o jak najmniejszym koszcie wykonawczym
w najgorszym przypadku. Jako element wyjciowy posuymy si kodem na listingu 7.5,
ktry postaramy si usprawni. Kod ten nie wykorzystuje rozgazie i wykonuje si
w najgorszym wypadku w 260 instrukcjach, wliczajc operacje wstpne i kocowe.
Listing 7.5. Prosta forma operacji compress
&1/5(/
((%@@2F#(5BH&(/$#$% 12$


1
%/

 % 
L%
 

// 

!2'3/K
 
!

Mona usprawni ten kod za pomoc metody prefiksu rwnolegego (zob. rozdzia 5.,
strona 85) z wykorzystaniem operacji rnicy symetrycznej [GLS1]. Operacj prefiksu
rwnolegego z wykorzystaniem rnicy symetrycznej oznaczmy PP-XOR. Gwny
pomys polega tu na wyodrbnieniu bitw argumentu x, ktre naley przesun w prawo o nieparzyst liczb pozycji i na wykonaniu tego przesunicia. Operacj t mona
uproci przez koniunkcj x z mask w celu usunicia niepotrzebnych bitw. Bity maski przesuwamy w ten sam sposb. Nastpnie identyfikujemy te bity w x, ktre naley
przesun o liczb miejsc bdc nieparzyst wielokrotnoci dwjki (2, 6, 10 itd.)
i przesuwamy te bity w x oraz w masce. Nastpnie identyfikujemy i przesuwamy bity,
ktre naley przesun o nieparzyst wielokrotno liczby 4, nastpnie powtarzamy t
operacj dla nieparzystej wielokrotnoci 8 a nastpnie dla bitw, ktre naley przesun o 16 pozycji.
Algorytm ten (ktrego pierwsz publikacj przypisuje si [GLS1]) wydaje si by do
trudny do zrozumienia i taki sposb zrealizowania czegokolwiek nie wydaje si by
w ogle moliwy, zatem operacje wykorzystywane przez ten algorytm omwimy z nieco wiksz szczegowoci. Zamy, e naszymi wartociami wejciowymi s:

Rozdzia 7. Manipulacja bitami i bajtami

139

$%&"'4#3/15J 2FB ,+)


/











    

Kada litera w symbolizuje jeden bit (o wartoci 0 lub 1). Liczba poniej kadej jedynki w masce oznacza liczb miejsc, o ktre naley przesun w prawo dany bit sowa .
Jest to liczba zer w masce na prawo od tego miejsca. Jak wspomniano wczeniej, wygodnie jest oczyci z niepotrzebnych bitw, co da w wyniku:
$4#2B,+

Plan polega na okreleniu bitw, ktre przesuwaj si o nieparzyst liczb miejsc w prawo i przesun je o jedn pozycj. Przypomnijmy, e operacja PP-XOR w wyniku daje 1
na kadej pozycji, na ktrej liczba jedynek od tego miejsca (wcznie) w prawo jest nieparzysta. My chcemy natomiast zidentyfikowa miejsca, od ktrych w prawo liczba zer
jest nieparzysta. Moemy to wyliczy za pomoc zmiennej pomocniczej %JEE,
wyliczajc na niej PP-XOR.
Otrzymamy:
/#










/5















Zaobserwujemy, e % identyfikuje bity, ktre zawieraj zera bezporednio po swojej


prawej stronie, natomiast  sumuje te zera, modulo 2, od prawej strony. W ten sposb
 identyfikuje bity w , ktre posiadaj nieparzyst liczb zer po swojej prawej stronie.
Bity, ktre chcemy przesun o 1 to s te bity, ktre posiadaj nieparzyst liczb zer po
swojej prawej stronie (zidentyfikowane przez ) oraz w oryginalnej masce maj warto 1. Dlatego bity te zidentyfikujemy za pomoc .K:
/






Bity te mona przesun za pomoc nastpujcego wyraenia:


//0/ / 


Natomiast odpowiadajce im bity w przesuwamy za pomoc nastpujcego wyraenia:


/
0    


Przesuwanie odpowiednich bitw w  jest prostsze, poniewa wszystkie odpowiednie


bity maj warto 1. W tym przypadku operacja rnicy symetrycznej wycza bity, bdce jedynkami w , natomiast alternatywa bitowa wcza bity majce warto 0 w 
oraz w . Operacja ta moe rwnie wykorzystywa dwie operacje rnicy symetrycznej
lub, odpowiednio, odejmowania i dodawania. Wyniki, po odpowiednim przesuniciu
wybranych bitw, bd wyglda nastpujco:
/









$4#2,+

140

Uczta programistw

W nastpnej kolejnoci musimy przygotowa mask dla drugiej iteracji, gdzie nastpi wykrywanie bitw, ktre naley przesun w prawo o nieparzyst wielokrotno dwjki.
Zauwamy, e warto %KJ identyfikuje bity, ktre maj warto 0 bezporednio
z prawej strony w oryginalnej masce  oraz ktre posiadaj parzyst liczb zer po prawej stronie w oryginalnej masce. Wasnoci te cz si, tworzc wasnoci zmienionej
maski  (oznacza to, e % identyfikuje wszystkie miejsca w nowej masce , ktre ssiaduj z prawej strony z zerem oraz posiadaj parzyst liczb zer ze swojej prawej strony). Warto ta, po podsumowaniu przez PP-XOR, zidentyfikuje bity, ktre naley
przesun w prawo o nieparzyst wielokrotno dwjki (2, 6, 10 itd.) Procedura nasza
bdzie polegaa na przypisaniu tej wasnoci do % i wykonaniu drugiej iteracji wymienionych krokw. Nowa warto % wynosi:
/#










Kompletna funkcja w C operacji kompresji zostaa przedstawiona na listingu 7.6. Wykonuje si w staej liczbie 127 instrukcji podstawowego zestawu RISC, wliczajc czynnoci przygotowawcze oraz koczce funkcj. Listing 7.7 przedstawia sekwencj wartoci przyjmowanych przez rne zmienne w kluczowych punktach wylicze, z tymi
samymi wartociami, ktre zostay uyte w powyszej dyskusji. Zauwamy, e produktem ubocznym tej procedury jest skompresowana wersja oryginalnej maski .
Listing 7.6. Procedura compress z wykorzystaniem prefiksu rwnolegego
&1/5(/
/#(/5(/( 
 
/@@&BFA&/F51 B%% F
/#M/ 
@@%HB/F3&BFPB$515$24 1
"1 LL
/5/#0/# 
@@5"#Q213GF
/5/50/5 
/5/50/5 
/5/50/5 
/5/50/5 

//5/@@% F15BH&$
//0/ / 
 @@#1/54/F/
 /
0    
 @@#1/54/F
/#/#M/5
!
 
!

Listing 7.7. Wykorzystanie prefiksu rwnolegego przy operacji compress


$%&"'4#3/15J 2FB ,+)
/










$4#2B,+
(
512F3&B??

/#










/5














/









$4#2,+

Rozdzia 7. Manipulacja bitami i bajtami


(
512F3&B??

/#









/5










/



/







$4#2B,+

(
512F3&B??

/#




/5




/




/





$4#2B,+

(
512F3&B??

/#


/5


/


/



$4#2B,+

(
512F3&B??

/#

/5



/


/


$4#2B,+

141

Na 64-bitowej maszynie obsugujcej podstawowy zestaw instrukcji RISC algorytm


z listingu 7.6. wymaga 169 instrukcji, natomiast najgorszy przypadek algorytmu z listingu 7.5 wykorzystuje 516 instrukcji.
Liczb instrukcji wykorzystywanych przez algorytm z listingu 7.6 mona jeszcze zredukowa, o ile maska  jest staa. Takie zaoenie mona przyj w dwch przypadkach:
1. Wykonanie funkcji 
,,D LF nastpuje w ptli, w ktrej warto  jest

niezmienna, cho moe nie by znana z gry.


2. Warto  jest znana z gry i kod funkcji 
,, jest generowany

z wyprzedzeniem, na przykad przez kompilator.


Zauwamy, e warto przypisywana zmiennej w ptli na listingu 7.6 nie jest wykorzystywana gdziekolwiek w ptli za wyjtkiem przypisa zmiennej . Warto zmiennej
zaley wycznie od niej samej i od wartoci zmiennej .. Dziki temu mona zmodyfikowa ptl w taki sposb, e wszystkie odwoania do zostan usunite, natomiast pi
kolejnych wartoci . zostanie zapisanych w zmiennych ., ., .. W pierwszym
opisanym wyej przypadku funkcja nie wykorzystujca odwoa do moe zosta
umieszczona poza ptl, w ktrej wystpuje wywoanie 
,,D LF, natomiast w ptli
umiecimy nastpujce wyraenia:
/
/0
/
0
/0
/0
/0

 
 
 
 
 

 

 
 
 
 


142

Uczta programistw

Dziki temu w ptli mamy tylko 21 instrukcji (adowanie staych mona zrealizowa
poza ptl), co stanowi spore usprawnienie w porwnaniu do 127 instrukcji wykorzystanych w penej wersji z listingu 7.6.
W drugim opisanym przypadku, w ktrym warto  jest znana z gry, mona zrobi podobn modyfikacj, lecz moliwe s dalsze usprawnienia. By moe jedna z piciu
masek ma warto 0, w tym przypadku mona pomin jeden z powyszych wierszy
przypisa. Na przykad zamy, e maska . jest rwna 0, co oznacza, e w nie ma
adnych pozycji, ktre naley przesun o nieparzyst liczb miejsc, natomiast . bdzie rwne 0 w przypadku, gdy aden bit nie musi by przesunity o wicej ni 15 pozycji w prawo itd.
Za przykad przyjmijmy nastpujc mask:
/
















Maski kolejnych etapw bd miay nastpujce wartoci:


/








/









/




/


/

Kod moe zosta skompilowany z pominiciem zbdnych instrukcji, poniewa ostatnia


maska ma warto 0, dziki czemu operacja kompresji wykona si w 17 instrukcjach
(nie liczc adowania masek do rejestrw). Wynik ten nie jest tak dobry, jak przedstawiony na stronie 128 (13 instrukcji, nie liczc adowania masek), ktra wykorzystuje
fakt wyboru naprzemiennych bitw.

Wykorzystanie instrukcji wstawiania i ekstrakcji


W przypadku, gdy procesor udostpnia instrukcje wstawiania (ang. insert), najlepiej
z wartociami bezporednimi okrelajcymi pole bitowe w rejestrze wynikowym, liczba
wykorzystanych instrukcji moe zosta jeszcze zmniejszona. Wykorzystujc instrukcj
wstawiania moemy rwnie unikn blokowania rejestrw przechowujcych maski.
Rejestr wynikowy jest ustawiany na warto 0 a nastpnie dla kadej cigej grupy jedynek w masce  zmienna jest przesuwana w prawo, wyrwnujc do prawej kolejne
pole. Instrukcja insert suy do wstawienia odpowiednich bitw zmiennej na odpowiednie miejsce w rejestrze wynikowym. Dziki temu caa operacja wykorzystuje 2n + 1
instrukcji, gdzie n oznacza liczb pl (grup ssiadujcych jedynek) w masce. W najgorszym przypadku operacja potrzebuje 33 instrukcje, poniewa najwiksza moliwa liczba
pl wynosi 16 (co stanowi mask z naprzemiennych jedynek i zer).
Przykad sytuacji, w ktrej metoda wykorzystujca wstawianie wykona si w znacznie mniejszej liczbie instrukcji stanowi maska  3. Wykonanie kompresji
z wykorzystaniem tej maski wymaga przesunicia bitw o 1, 2, 4, 8 oraz 16 pozycji.
W przypadku metody wykorzystujcej prefiks rwnolegy algorytm wykona si w 21

Rozdzia 7. Manipulacja bitami i bajtami

143

instrukcjach, lecz w przypadku zastosowania wstawiania potrzebne jest tylko 11 instrukcji (w masce wystpuje pi pl jedynek). Bardziej ekstremalnym przypadkiem jest
na przykad  . W tym przypadku naley przesun tylko jeden bit o 31 pozycji, co w przypadku metody wykorzystujcej prefiks rwnolegy wymaga 21 instrukcji, natomiast metoda wykorzystujca wstawianie wykorzysta tylko jedn instrukcj
(przesunicie w prawo o 31).
W operacji kompresji ze znan mask mona rwnie wykorzysta instrukcj ekstrakcji
(ang. extract), dziki czemu algorytm bdzie wymaga 3n 2 instrukcji, gdzie n jest
liczb pl jedynek w masce.
Z naszych rozwaa wynika jednoznaczny wniosek, e wybr optymalnego kodu realizujcego operacj kompresji ze znan mask nie jest atwym zadaniem.

Kompresja do lewej strony


W celu wykonania kompresji bitw do lewej strony mona oczywicie wykorzysta dopenienie argumentu oraz maski, skompresowa je do prawej strony a nastpnie wykona odbicie wyniku. Inny sposb polega na skompresowaniu do prawej a nastpnie
przesunicie wyniku w lewo o pop(m ) pozycji. Sposoby te mog dawa zadowalajce
wyniki, jeli wykorzystywany procesor udostpnia instrukcje wykonujce odbicie bitowe
(ang. bit reversal) lub instrukcj zliczania populacji. W przeciwnym wypadku mona
w prosty sposb zaadaptowa algorytm z listingu 7.6. Po prostu zmieniamy kierunek wykonywanych przesuni, za wyjtkiem dwch wykonujcych EE (osiem wyrae
do zmiany).

7.5. Uoglnione permutacje,


operacja typu owce i kozy
W celu wykonania operacji oglnych permutacji bitw w sowie lub jakiejkolwiek
uporzdkowanej strukturze danych, pierwszym problemem, z ktrym naley si zmierzy jest sposb reprezentacji permutacji. Tego typu operacji nie mona reprezentowa w sposb bardzo zwarty. Poniewa w sowie 32-bitowym istnieje 32! moliwych
permutacji, w celu reprezentacji jednej z moliwych permutacji potrzeba co najmniej
log2 (32!) = 118 bitw, czyli trzy sowa plus 22 bity.
Jeden z interesujcych sposobw reprezentacji permutacji jest zwizany z operacjami
kompresji, omwionymi w podrozdziaach 7.1 7.4 [GLS1]. Rozpoczynamy od bezporedniej metody okrelajcej pozycje, na ktre maj przej poszczeglne bity. Na przykad wemy pod uwag permutacj dokonywan za pomoc przesunicia cyklicznego
w lewo o cztery pozycje, bit na pozycji 0 przesuwa si na pozycj 4, 1 na pozycj 5,
31 przesuwa si na pozycj 3. Permutacja ta moe zosta zapisana w postaci wektora
32 5-bitowych indeksw:

144

Uczta programistw





...








Traktujc te wektory jako macierz bitow naley wykona transpozycj macierzy a nastpnie odbi j wedug przektnej w taki sposb, e grny wiersz bdzie zawiera najmniej znaczce bity wektorw a wynik bdzie w schemacie little-endian. W ten sposb
powysze wektory moemy przechowa w postaci nastpujcej macierzy bitowej:
5DE
















5D
E
















5DE







5DE




5DE



Kady bit sowa GH zawiera najmniej znaczcy bit numeru pozycji, na ktr przesuwa
si odpowiedni bit sowa . Kady bit sowa GH zawiera kolejny bit numeru pozycji
itd. Jest to sytuacja podobna do zapisu maski w ., wykorzystywanego w poprzednim
podrozdziale, z t rnic, e . odnosio si do nowej maski w algorytmie kompresji,
nie do oryginalnej maski.
Operacja kompresji, ktra jest nam teraz potrzebna, musi skompresowa do lewej wszystkie bity oznaczone w masce wartoci 1, natomiast do prawej skompresowa wszystkie
bity oznaczone w masce wartoci 02. Sposb ten nazywany jest czasem operacj rozdzielania owiec i kozw3 (ang. sheep and goats SAG) lub uoglnionym odtasowaniem (ang. generalized unshuffle). Wynik takiej operacji mona wyznaczy za pomoc
nastpujcego wyraenia:
R 6(/&1/5S3" (/ &1/5(M/

Wykorzystujc SAG jako operacje podstawow oraz permutacj  opisan wyej, wynik przeksztacenia sowa mona wyznaczy w nastpujcych 15 krokach:
R 6(5DE
5D
ER 65D
E(5DE
5DER 65DE(5DE
5DER 65DE(5DE
5DER 65DE(5DE
R 6(5D
E
5DER 65DE(5D
E
2

W przypadku, gdy wykorzystywany jest format big-endian do lewej naley skompresowa bity oznaczone
w masce wartoci 0, natomiast do prawej bity oznaczone wartoci 1.
Nazwa pochodzi z jednej z przypowieci w ewangelii wedug w. Mateusza (Mat 25, 3233): I zgromadz
si przed Nim wszystkie narody, a On oddzieli jednych [ludzi] od drugich, jak pasterz oddziela owce
od kozw. Owce postawi po prawej, a kozy po swojej lewej stronie. Z atwoci mona dostrzec
analogi rozdzielanie bitw na praw i lew stron rejestru wynikowego przyp. red.

Rozdzia 7. Manipulacja bitami i bajtami

145

5DER 65DE(5D
E
5DER 65DE(5D
E
R 6(5DE
5DER 65DE(5DE
5DER 65DE(5DE
R 6(5DE
5DER 65DE(5DE
R 6(5DE

W tych krokach operacja SAG jest wykorzystywana w celu wykonania stabilnego sortowania o podstawie 2 (ang. stable binary radix sort). W pierwszym kroku wszystkie
bity w , dla ktrych GH, zostaj przesunite do lewej powki wynikowego sowa, natomiast wszystkie bity, dla ktrych GH  , zostaj przeniesione do prawej
powki. Oprcz tych przesuni kolejno bitw nie ulega zmianie (std wanie to
sortowanie nosi miano stabilnego). W kolejnych wierszach w podobny sposb sortowane s klucze wykorzystywane w nastpnym etapie sortowania. Szsty wiersz kodu
wykonuje sortowanie na podstawie drugiego mniej znaczcego bitu klucza itd.
Podobnie do omawianej wczeniej kompresji, w sytuacji, gdy permutacja  jest wykorzystana na wikszej liczbie sw moemy uzyska znaczny przyrost wydajnoci, jeli
wstpnie wyliczymy parametry niezbdne do poszczeglnych etapw sortowania. Macierz permutacji mona rozpisa w nastpujcy sposb:
5D
ER 65D
E(5DE
5DER 6R 65DE(5DE(5D
E
5DER 6R 6R 65DE(5DE(5D
E(5DE
5DER 6R 6R 6R 65DE(5DE(5D
E(5DE(5DE

Nastpnie kada z permutacji jest wykonywana w nastpujcy sposb:


R 6(5DE
R 6(5D
E
R 6(5DE
R 6(5DE
R 6(5DE

Bardziej bezporedni (i zapewne mniej ciekawy) sposb reprezentacji uoglnionych permutacji bitw w sowie polega na zapisie permutacji w postaci sekwencji 32 5-bitowych
indeksw.
Indeks o numerze k stanowi numer bitu w rdle, z ktrego pochodzi k-ty bit wyniku (jest
to lista typu pochodzi z, w odrnieniu od metody SAG, w ktrej lista okrela sytuacj przechodzi do). Informacje te mona upakowa w szeciu sowach 32-bitowych, co
wymaga zastosowania szeciu sw do przechowania 32-bitowych indeksw. Instrukcj t mona zaimplementowa sprztowo, na przykad w postaci:
% $ 'T (T(T(

146

Uczta programistw

Rejestr =- jest rejestrem wynikowym oraz rdowym, rejestr = zawiera bity, ktre
chcemy podda permutacji, rejestr = zawiera natomiast sze 5-bitowych indeksw
(z dwoma nieuywanymi bitami). Instrukcja ta wykonuje nastpujc operacj:
t (t << 6) | x i0 x i1 x i2 x i3 x i4 x i5
Zawarto rejestru wynikowego t zostaje przesunita w lewo o sze pozycji a w miejsce powstae w efekcie tego przesunicia zostaj wstawione wybrane bity sowa x.
Pobrane bity s okrelone szecioma 5-bitowymi indeksami sowa i w kolejnoci od
lewej do prawej. Kolejno bitw w indeksach moe by interpretowana w formacie
little-endian lub big-endian a wybr najprawdopodobniej byby dostosowany do specyfiki konkretnego procesora.
W celu dokonania permutacji sowa naley zastosowa sekwencj szeciu takich instrukcji, wszystkie z tymi samymi wartociami =- oraz = lecz z rnymi rejestrami indeksw. W pierwszym rejestrze indeksowym w sekwencji znaczenie miayby tylko indeksy i4
oraz i5, poniewa bity wybrane przez pozostae cztery indeksy zostan i tak przesunite
poza wynik =-.
Implementacja tej metody z ca pewnoci pozwala na powtrzenie wartoci indeksw,
zatem instrukcja ta moe zosta uyta rwnie w innym celu ni permutacja bitw. Mona j zastosowa w celu powtrzenia dowolnego bitu dowoln liczb razy w rejestrze wynikowym. Operacja SAG nie posiada wasnoci pozwalajcej na takie uoglnienie.
Implementacja tej instrukcji w postaci szybkiej instrukcji (tzn. wykonujcej si w pojedynczym cyklu procesora) nie jest zadaniem niewykonalnym. Ukad wyboru bitw
skada si tutaj z szeciu multiplekserw MUX 32:1. W przypadku, gdyby zbudowa je
z piciu segmentw multiplekserw MUX 2:1 we wspczesnej technologii (6 31 = 186
MUX w sumie), instrukcja ta byaby szybsza od 32-bitowej instrukcji dodawania [MD].
Operacja permutacji bitw ma zastosowanie w kryptografii, natomiast bardzo zbliona
operacja permutacji fragmentw sw (na przykad permutacja bajtw w sowie) ma
zastosowanie w grafice komputerowej. Obydwa te zastosowania bd operowa na wartociach 64-bitowych lub wrcz na 128-bitowych, natomiast na wartociach 32-bitowych
zdecydowanie rzadziej. Operacje SAG oraz bitgather daj si oczywicie zmodyfikowa w prosty sposb rwnie dla sw o wspomnianych wielkociach.
W celu wykonania szyfrowania lub odszyfrowania komunikatu za pomoc standardu DES
(Data Encryption Standard) naley wykona szereg przeksztace podobnych do permutacji. W pierwszej kolejnoci jest wykonywane generowanie klucza i zachodzi to jednorazowo podczas sesji. Operacja ta wymaga zastosowania 17 odwzorowa przypominajcych permutacje. Pierwsze z nich, nazywane permuted choice 1 dokonuje odwzorowania
64-bitowej wartoci na warto 56-bitow (wybiera 56 bitw pomijajc bit parzystoci
i wykonuje na nich permutacj). Nastpnie wykonywane jest 16 odwzorowa permutacyjnych z 56 bitw na 48 bitw, z ktrych wszystkie wykorzystuj to samo odwzorowanie, zwane permuted choice 2.

Rozdzia 7. Manipulacja bitami i bajtami

147

Po etapie generowania klucza kady 64-bitowy blok bitw w komunikacie zostaje poddany 34 operacjom permutacyjnym. Pierwsz i ostatni operacj stanowi permutacje
64-bitowej wartoci, z ktrych jedna stanowi odwrotno drugiej. Wykonuje si 16 permutacji z powtrzeniami, ktre odwzorowuj wartoci 32-bitowe na wartoci 48-bitowe,
wykorzystujc to samo odwzorowanie. Na kocu wykonywane jest 16 32-bitowych
permutacji, wykorzystujcych t sam permutacj. W caej operacji wykorzystywane jest
wiele powtrze szeciu rnych odwzorowa. S one stae i zostay opisane w [DES].
Algorytm DES jest przestarzay i w roku 1998 organizacja Electronic Frontier Foundation udowodnia, e z zastosowaniem specjalnego sprztu jest moliwe zamanie algorytmu DES. W ramach tymczasowego rozwizania National institute of Standards and
Technology (NIST) opracowa rozwizanie pod nazw Triple DES, ktre polega na
trzykrotnym wykonaniu algorytmu DES na kadym z 64-bitowych blokw, za kadym
razem wykorzystujc inny klucz (co oznacza, e klucz skada si z 192 bitw, wliczajc
24 bity parzystoci). Z tego powodu algorytm ten wymaga wykonania trzykrotnie wikszej liczby permutacji ni ma to miejsce w standardowym algorytmie DES zarwno
w operacjach szyfrowania, jak i deszyfrowania.
Prawdziwy nastpca algorytmw DES oraz Triple DES, algorytm AES (ang. Advanced Encription Standard, znany wczeniej pod nazw algorytmu Rijndael) w ogle nie
wykorzystuje permutacji na poziomie bitw. Jedyn operacj zblion do permutacji
jest przesunicie cykliczne 32-bitowych sw o wielokrotnoci liczby 8. Inne metody
kryptograficzne proponowane lub rzeczywicie wykorzystywane z reguy wykorzystuj
znacznie mniejsz liczb permutacji bitw ni ma to miejsce w algorytmie DES.
Porwnujc dwa sposoby implementacji permutacji, sposb wykorzystujcy instrukcj
bitgather ma nastpujce zalety:
 prostszy proces przygotowania indeksw z danych opisujcych permutacj;
 prostszy sposb implementacji sprztowej;
 bardziej uoglnione odwzorowania.

Metoda SAG posiada natomiast nastpujce zalety:


 permutacja jest wykonywana w piciu, zamiast szeciu instrukcjach;
 w przypadku implementacji sprztowej instrukcja SAG wymagaaby tylko

dwch rejestrw (co ma znaczenie w przypadku niektrych implementacji


architektury klasy RISC);
 atwiej rozwin j do obsugi wartoci zoonych z dwch sw (ang.

doubleword);
 bardziej wydajnie realizuje permutacj czci sw.

Punkt trzeci z powyszych rozwaa szerzej omwiono w pozycji [LSY]. Instrukcja SAG
pozwala na realizacj uoglnionej permutacji wartoci zoonych z dwch sw za pomoc dwch wywoa instrukcji SAG, kilku dodatkowych instrukcji z podstawowego
zestawu RISC oraz dwch penych permutacji pojedynczych sw. Instrukcja bitgather

148

Uczta programistw

pozwala na realizacj tego celu za pomoc trzech permutacji pojedynczych sw plus


pi instrukcji z podstawowego zestawu RISC. Nie uwzgldniamy operacji przygotowawczych permutacji, generujcych nowe wartoci uzalenione wycznie od permutacji. Odkrycie tych sposobw pozostawiamy jako wiczenie dla Czytelnika.
Zatrzymajmy si jeszcze chwile przy punkcie 4. Chcc na przykad dokona permutacji
czterech bajtw w sowie za pomoc instrukcji bitgather, musimy wykona sze instrukcji, dokadnie tak samo, jak ma to miejsce w przypadku uoglnionej operacji permutacji za pomoc instrukcji bitgather. Natomiast za pomoc instrukcji SAG mona
tego dokona w dwch instrukcjach, zamiast piciu wymaganych przez uoglnion
wersj algorytmu permutacji wykorzystujcego instrukcj SAG. Przyrost wydajnoci bdzie mia miejsce rwnie w przypadku, gdy rozmiar czci sw nie jest potg liczby
dwa. Wtedy liczba wymaganych krokw wynosi log 2 n , gdzie n okrela liczb czci
sowa, nie liczc czci sowa niebiorcych udziau w permutacji.
W pozycji [LSY] omwiono dokadniej instrukcje SAG oraz bitgather (nazywane tam,
odpowiednio, GRP oraz PPERM), jak rwnie inne moliwe instrukcje permutacji oparte
na sieciach lub te tablicach przegldowych.

7.6. Zmiana kolejnoci oraz


transformacje oparte na indeksach
Wiele prostych modyfikacji kolejnoci bitw w sowie procesora ma zwizek z jeszcze
prostszymi operacjami na wsprzdnych, czyli indeksach, bitw [GLS1]. Zwizki te
odnosz si do zmiany kolejnoci elementw w kadej jednowymiarowej macierzy,
pod warunkiem, e liczba elementw w tablicy stanowi potg cakowit dwjki. W zastosowaniach programistycznych najczciej elementy macierzy s sowami procesora
lub wikszymi elementami.
W ramach przykadu zewntrzne tasowanie zupene elementw w macierzy A o rozmiarze 8 z wynikiem w macierzy B mona zapisa za pomoc nastpujcych przesuni:
A0 B0;

A1 B2;

A2 B4;

A3 B6;

A4 B1;

A5 B3;

A6 B5;

A7 B7.

Kady indeks macierzy B odpowiada indeksowi macierzy A przesunitemu cyklicznie


w lewo za pomoc obrotu 3-bitowego. Operacja zewntrznego odtasowania zupenego
(ang. outer perfect unshuffle) jest oczywicie realizowana za pomoc odpowiedniej operacji przesunicia cyklicznego w prawo. Niektre z podobnych zalenoci prezentujemy
w tabeli 7.1. W opisie n okrela liczb elementw w macierzy, lsb okrela najmniej
znaczcy bit, natomiast przesunicia cykliczne indeksw s realizowane na log2n bitach.

Rozdzia 7. Manipulacja bitami i bajtami

149

Tabela 7.1. Zmiana kolejnoci oraz transformacje oparte na indeksach


Transformacja w oparciu o indeksy
Zmiana kolejnoci bitw

Indeks w macierzy,
numeracja big-endian

Numeracja little-endian

Odwrcenie kolejnoci

Dopenienie

Dopenienie

Odwrcenie bitowe lub uoglnione


odwrcenie kolejnoci (strona 122)

Rnica symetryczna ze sta

Rnica symetryczna ze sta

Przesunicie cykliczne w lewo


o k pozycji

Odjcie k (mod n)

Dodanie k (mod n)

Przesunicie cykliczne w prawo


o k pozycji

Dodanie k (mod n)

Odjcie k (mod n)

Zewntrzne tasowanie zupene

Przesunicie cykliczne w lewo


o jedn pozycj

Przesunicie cykliczne w prawo


o jedn pozycj

Zewntrzne odtasowanie zupene

Przesunicie cykliczne w prawo


o jedn pozycj

Przesunicie cykliczne w lewo


o jedn pozycj

Wewntrzne tasowanie zupene

Przesunicie cykliczne w lewo


o jedn pozycj, nastpnie
dopenienie lsb

Dopenienie lsb, nastpnie


obrt w prawo o jedn pozycj

Wewntrzne odtasowanie zupene

Dopenienie lsb, nastpnie


obrt w prawo o jedn pozycj

Przesunicie cykliczne w lewo


o jedn pozycj, nastpnie
dopenienie lsb

Przesunicie cykliczne (w lewo


Transpozycja macierzy 88 bitw
przechowywanej w 64-bitowym sowie lub w prawo) o trzy pozycje

Przesunicie cykliczne (w lewo


lub w prawo) o trzy pozycje

Odkodowanie FFT

Odwrcenie kolejnoci bitw

Odwrcenie kolejnoci bitw

You might also like