Płynąc potokiem
Nie pomylę się pewnie twierdząc, iż na każdym kroku słyszysz
o technikach potokowych czy transferach potokowych.
Dopóki miałeś szansę zetknąć się z tym terminem jedynie przy
okazji czytania instrukcji do płyty głównej (od dłuższego
czasu pamięć podręczna cache płyt głównych i procesorów
pracuje w trybie potokowym) i wiedziałeś, że dzięki temu
komputer pracuje szybciej, nie było najmniejszego problemu. Jednak
potokowość wcale nie musi oznaczać szybkości, co widać choćby
na przykładzie nowego, hiperpotokowego procesora Intel Pentium 4 -
dobrze jest więc wiedzieć, na czym potokowość polega i jakie
są jej wady i zalety.
Przetwarzanie sekwencyjne
Jak wyglądałby transfer danych (na przykład z pamięci
operacyjnej) bez uczestnictwa potoku? Dane byłyby odnajdywane,
przekazywane do bufora wyjściowego, potem przenoszone kolejnymi
stopniami buforów płyty głównej, układu obsługującego pamięć
oraz procesora aż do rejestru procesora. Powiesz: nic niezwykłego,
tak przecież chyba się dzieje. I masz rację!
Zastanów się jednak ile będziemy czekać od momentu
dostarczenia jednej porcji danych do dotarcia kolejnej? Zgadłeś:
dokładnie tyle samo, ile czekaliśmy na pierwszą. Czyli
zdecydowanie zbyt długo.
Przykład ten można zilustrować analogią motoryzacyjną:
dysponując autostradą możesz oczywiście wpuścić na jednym końcu
samochód, poczekać, aż dojedzie do końca, a po otrzymaniu
sygnału o pomyślnym dotarciu wysłać kolejny. Możesz jednak
przyspieszyć całą sprawę wysyłając od razu wszystkie czekające
auta: jeśli wszystkie pojadą z taką samą prędkością, dojadą
w takiej samej kolejności, w jakiej zostały wysłane.
I w ten sposób odkryliśmy właśnie...
Przetwarzanie potokowe
Już chyba wiesz, o co w tym wszystkim chodzi: wystarczy podzielić
drogę, którą muszą przebyć dane, na drobne kawałki.
Pierwszy kawałek należy ładować danymi tak szybko, jak tylko się
da, a pozostałe będą te dane obrabiać i przekazywać
dalej trzymając tempo (oczywiście muszą być odpowiednio
szybkie). Na pierwszy kawałek poczekasz sobie tak czy tak, jednak
potem co chwila z końca "rury" wypadać będzie
kolejna partia informacji.
Najładniejszym analogiem potoku jest właśnie wspomniana przed
chwileczką rura: jeśli wrzucisz do leżącej prawie poziomo
rury kulkę, w jakimś czasie doleci ona do końca. Jeśli jednak
zaczniesz wrzucać całą masę kulek, zaraz po pojawieniu się
pierwszej pojawią się i inne, gdyż turlały się zaraz za nią.
Taką właśnie "rurę na dane", nazwaną elegancko potokiem
(ang. pipeline), znaleźć można w wielu nowoczesnych układach
scalonych. Dlaczego? Sygnały elektryczne rozchodzą się niestety
tylko z prędkością bliską prędkości światła, a to dla
megahercowych układów dość sporych rozmiarów jest za mało.
Zanim sygnał dotarłby do końca układu (nie mówiąc już o
drugim końcu płytki drukowanej, na której zamontuje się układ),
dawno zacząłby się drugi takt pracy. Rezultat - całkowita
katastrofa. Konstruktorzy dzielą więc układy i płyty na kawałki,
które są wystarczająco małe, by prąd zdążył przebiec przez
każdą ich ścieżkę w czasie trwania jednego cyklu zegarowego, a
następnie łączą te kawałki tak, aby nawzajem przekazywały
sobie dane.
Rozwiązanie idealne?
Po tej lekturze mógłbyś pomyśleć, że nie ma na tym świecie
nic lepszego od techniki potokowej, a po podzieleniu układu na
odpowiednią liczbę kawałków zbudowanie procesora taktowanego
zegarem 10 GHz jest banalnie proste. Jeśli tak, niestety muszę
Cię rozczarować.
Tam, gdzie bloki danych są naprawdę duże, a zbyt mała
przepustowość (transfer) zmorą konstruktora, potokowość jest
zbawieniem. Nie znajdziesz już chyba podsystemu pamięci
operacyjnej albo pamięci buforowej (cache) nie pracującego
w trybie potokowym. Jednak jest ku temu powód: podsystemy te
praktycznie zawsze muszą przesłać na raz bardzo dużo
kolejnych danych (o tym dlaczego to robią i jak działa pamięć cache,
napiszę może kiedyś osoby artykuł).
Porzućmy więc pamięci i zajmijmy się procesorami: te, w zależności
od przydzielonego zadania, albo przetwarzają dane w sposób ciągły,
albo beznadziejnie miotają się między różnymi danymi, różnymi
operacjami i różnymi fragmentami kodu. Prawdę mówiąc, to drugie
robią prawie zawsze. Oczywiście, są programy, które obrabiają
wielkie, ciągłe bloki danych: na przykład programy testowe Intela
pokazujące cudowną szybkość pamięci Rambus czy też procesora
Pentium 4. Przyznasz jednak, że ich użyteczność jest bardzo wątpliwa.
Bliskie ideału są programy obrabiające pliki multimedialne -
na przykład z muzyką czy obrazem wideo. Technika potokowa może w
takich przypadkach rozwinąć swoje skrzydła i obśmiewana tu
przeze mnie kombinacja Pentium 4 plus RDRAM jest naprawdę
diabelnie szybka. Jest jednak pewien problem: mało kto tak naprawdę
zajmuje się głównie np. obróbką wideo i mało kto skorzysta z
tej mocy. A już uruchomienie prostego pakietu biurowego może
sprowadzić na ziemię użytkownika drogiej i obfitej w gigaherce
maszyny. Program będzie działał po prostu wolno.
Pytasz: co zabija zysk wynikający z potokowości? Odpowiedź
jest bardzo prosta.
Opóźnienia
Gdy program co chwila wykonuje skok w jakieś odległe miejsce
pamięci lub raz po raz sięga po dane oddalone od siebie w pamięci
o setki kilobajtów, przestaje mieć znaczenie szybkość, z jaką
potok może z siebie wyrzucać dane; znaczenia nabiera natomiast
czas, po którym na końcu potoku pojawia się pierwsza informacja -
czas, nazywany opóźnieniem (ang. latency).
Porównajmy na przykład pracę procesorów Pentium III i Pentium
4 wykonujących choćby prosty program do obsługi poczty
elektronicznej. Programy tego typu co chwila wykonują skoki w różne
miejsca pamięci. Co gorsza, są to w znakomitej większości skoki
warunkowe, w przypadku których do samego końca nie wiadomo, czy
powinny być wykonane, czy też nie (przewidywanie skoków to też
materiał na osobny artykuł). Oba procesory w przypadku takiego
skoku muszą opróżnić potok, po czym na nowo zacząć go zapełniać.
No dobra, to zapełniajmy go. W Pentium III potok ma głębokość
10, więc na pierwsze rezultaty działania procesora po skoku
warunkowym czekamy dziesięć cykli zegara. A Pentium 4? Jego
hiperpotokowa architektura to potoki o głębokości... 20! Tak -
dwadzieścia poziomów każdego potoku, a więc minimum
dwadzieścia cykli zegara straconych przy każdym skoku.
W skrajnym przypadku procesor Pentium IV o częstotliwości 1.5
GHz powinien mieć wydajność Pentium III 750 MHz. Tak źle nie
jest nigdy, ale może być prawie tak źle, jeśli do sprawy dołączy
się "przyszłość rynku pamięci według Intela", czyli
pamięci Rambus RDRAM.
Pamięć RDRAM ma modną ostatnio architekturę quasi-szeregową:
ścieżka danych jest bardzo wąska (8 bitów w porównaniu do 64
bitów oferowanych przez moduły DIMM SDRAM), lecz taktowana wysoką
częstotliwością i pracująca w trybie potokowym. Może już jesteś
w stanie zgadnąć, jaka jest największa wada takiego rozwiązania?
Tak, bardzo dobrze! Opóźnienia! Zanim potok pamięci się zapełni
i do procesora dopłynie pierwszy wiersz danych, musi on stać i
czekać. Potem potok dostarcza informacje z niesamowitą
wydajnością, ale zanim spełni swoją funkcję, procesor już
zacznie wykonywać skok warunkowy, opróżni potoki swoje i pamięci
i zabawa zaczyna się od początku.
Przesadzenie z potokami ma więc skutki pozytywne i negatywne: co
prawda niektóre programy uwielbiają długie potoki i nigdy
nie dopuszczają do ich opróżnienia, lecz wyraźna większość
czerpie zyski z jak najmniejszych opóźnień - a wydłużanie potoków
zazwyczaj liniowo zwiększa opóźnienia.
Na koniec
Od architektury potokowej przy obecnym stopniu rozwoju
elektroniki uciec się nie da. Nie miałoby to zresztą sensu, biorąc
pod uwagę oczywistą przewagę krótkich potoków nad
przetwarzaniem czysto sekwencyjnym. O tym jednak, czy potok da nam
szybkość, czy też spowolni pracę całej maszyny, decyduje
dobranie jego głębokości do konkretnego zastosowania. Procesor o
bardzo wysokiej częstotliwości zegara i bardzo długim potoku świetnie
sprawdzi się przy np. rekompresji filmu z formatu MPEG2
do MPEG4, lecz przy pisaniu tekstu i czytaniu stron WWW
znacznie szybszy będzie procesor o znacznie mniejszej częstotliwości
zegara i znacznie krótszym potoku (tak, jak np. rodzina AMD
K6, której tylko sześcioelementowe potoki wspomagane niesamowicie
skuteczną jednostką przewidywania skoków do dzisiaj są wzorem do naśladowania).
Słusznego doboru głębokości potoku życzy Ci
Radosław Sokół
rsokol@iname.com
http://main.magsoft.com.pl/~rsokol/
|