Zainspirowany podcastami o historii komputerów (podcast #19 - część I oraz część II) postanowiłem przybliżyć Wam dokładniej zapomniane i nieużywane już technologie. Na początek tego małego cyklu będzie o pamięci. Moim zdaniem jej rozwój dyktował rozwój i produkcję komputerów, a nie na odwrót. Miała też wpływ na sposób programowania komputerów i dostęp do danych wynikowych. Temat jest bogaty, a technologii pamięci powstało wiele. Przez to wyszedł mi tak długi artykuł, że nawet mnie męczy jego czytanie. Dlatego podzieliłem go na trzy części. W pierwszej przedstawię wczesne technologie, z których tylko jedna przetrwała dłużej. Druga część przedstawi technologie niegdyś bardzo popularne, teraz już w większości zapomniane. Trzecia część zaś przedstawi technologie pamięci masowej, które w większości dotrwały do dzisiaj, oraz moje przeczucia na temat technologii, które mogą odejść do lamusa. Tak że zapraszam do czytania.
Słowo o architekturze i słowniczek pojęć
By lepiej zrozumieć zagadnienie pamięci, musimy najpierw poznać architekturę, a dokładniej to części składowe procesora. Nie będziemy zagłębiać się w tajniki najnowszych Ryzenów czy i9, ani w sekrety GPU. Spokojnie możemy sobie odpuścić tournée po ARMach, SoCach czy współczesnych mikrokontrolerach. Wystarczy Wam wiedzieć, że te same elementy są zarówno w nich, jak i w wielu pierwszych komputerach z lat 40stych i 50tych XX wieku. Ba, znajdziecie je nawet w opisie maszyny analitycznej Babbage'a.
Podstawowymi elementami niemal każdego procesora są: ALU, dekoder rozkazów, licznik rozkazów, rejestr rozkazów, układ kontrolny procesora i kilka rejestrów dodatkowych. ALU to inaczej jednostka arytmetyczno-logiczna, czyli element procesora, który wykonuje właściwą pracę. Do podstawowych operacji należą dodawanie, odejmowanie i porównywanie dwóch liczb binarnych. Bardziej rozbudowane układy potrafią przesuwać liczbę binarną w lewo lub w prawo, dodając z odpowiedniego końca zera, mnożyć dwie liczby, a czasem wykonywać nawet bardziej skomplikowane operacje, czasami na dużych zbiorach danych (tak działa wiele układów CISC, jak dawniejsze układy graficzne, DSP czy procesory komputerów osobistych od czasów Pentium). Dane te często znajdują się w rejestrach, czyli dedykowanych obwodach o pojemności najczęściej pojedyńczego słowa. Słowo to pojedyncza jednostka danych, jaką może przetworzyć ALU. Używam słów zamiast bajtów, bo wiele wczesnych procesorów miało słowa o nietypowych rozmiarach. Dla większości procesorów minimalna liczba rejestrów, to cztery: dwa rejestry wejściowe dla ALU, rejestr wyjściowy dla ALU i licznik rozkazów. Jest to specjalny rejestr, który wskazuje lokalizację w pamięci bieżącego rozkazu do wykonania. Dekoder rozkazów odczytuje ten rozkaz, umieszcza go w rejestrze rozkazów i steruje poszczególnymi elementami procesora, by ten rozkaz wykonać, po czym modyfikuje licznik rozkazów. Układ kontrolny odpowiada za kolejność wykonywania operacji w cyklu procesora: odczyt rozkazu z pamięci, załadowanie wartości do ALU, wykonanie operacji przez ALU, transfer danych do pamięci i przejście do następnego rozkazu.
No właśnie, pamięć. Poznaliśmy mimochodem pierwszy typ, czyli rejestry. Jest to najprostsza forma pamięci, zintegrowana w strukturze samego procesora do tego stopnia, że programista nie musi o tym myśleć, chyba że programuje w Assemblerze. Inne rodzaje pamięci zwykle są poza procesorem i dla jego pracy ich typy i budowa są mało istotne. Dlaczego? Ano dlatego, że typowy procesor czy mikroprocesor kontaktuje się ze światem za pomocą linii danych, które mogą łączyć się z wybranym przez rozkaz rejestrem, linii adresowych, które też mogą łączyć się z wybranym rejestrem, linii kierunku odczyt/zapis i linii, która sygnalizuje chęć odczytu lub zapisu. Pewnym wyjątkiem od tego podziału jest większość pierwszych komputerów, gdzie to dostępna pamięć dyktowała budowę procesora i jego prędkość działania.
Jeszcze słówko o architekturach. Są dwie podstawowe: harwardzka i von Neumanna. W architekturze harwardzkiej pamięć programu, czyli kolejne rozkazy do wykonania, jest oddzielona od pamięci, która przechowuje dane do przetworzenia. Wiele wczesnych komputerów miało taką budowę. Procesor w tym stylu ma oddzielne linie danych i adresowe dla pamięci programu i pamięci danych. W architekturze von Neumanna dane i instrukcje są w tej samej pamięci i używają tych samych linii do ich transferu, co spowalnia pracę (trzeba wykonać 2-3 transfery na każdy rozkaz), ale pozwala na łatwą samomodyfikację programu i oszczędza pamięć oraz liczbę linii do połączenia wszystkiego razem.
"Będziemy razem borować dziurki!" - karty i taśmy perforowane
Karty i taśmy perforowane wyprzedziły powstanie komputerów o ponad 200 lat. Basile Bouchon wykorzystał karty dziurkowane do automatyzacji pracy krosna, co pozwoliło na obniżenie kosztów produkcji tkanin. Joseph Marie Jacquard w 1804 roku zaprezentował automatyczną maszynę tkacką, w której wzory były programowane kartami dziurkowanymi. Przy okazji słowo "sabotaż" wywodzi się z tej ery: tkacze tracący zatrudnienie przez mechanizację produkcji wrzucali saboty (rodzaj obuwia) w tryby maszyn tkackich celem ich uszkodzenia.
Charles Babbage pracując nad swoimi maszynami zaproponował użycie kart dziurkowanych jako sposób na wprowadzanie danych i programów. Z kolei Jules Carpentier w 1881 roku zaprezentował pierwszą fisharmonię kontrolowaną przez zestaw kart dziurkowanych połączonych w taśmę. Jego system pozwalał muzykowi zagrać utwór, co automatycznie perforowało karty. Tak przygotowany utwór mógł być powielany mechanicznie. Wcześniej mechaniczne automaty grające wymagały, by dyski czy walce były wykonywane ręcznie, i do tego często z metalu.
Herman Hollerith opracował system zbierania informacji, wykonywania kart z tymi informacjami zakodowanymi oraz ich odczytu i zliczania wartości metodą elektromechaniczną, co zostało wykorzystane w czasie spisu powszechnego w USA w 1890 roku. Karty były umieszczane na łożu elektrod i dociskane od góry metalową płytką. Jeśli elektroda dotknęła płyty przez otwór w karcie, stosowny licznik rósł o jeden. Hollerith rozwinął swój pomysł i założył firmę produkującą maszyny sumujące, sortujące, perforujące i dekodujące karty dziurkowane. Firma ta istnieje do dzisiaj i jest znana pod nazwą IBM.
Taśmy perforowane rozwijały się równolegle. W 1842 Claude Seytre opatentował maszynę grającą na fortepianie sterowaną taśmą perforowaną. Do XX wieku pianole, czyli pianina automatyczne weszły do powszechnego użytku - można je zobaczyć zarówno w starych westernach, jak i we współczesnym serialu Westworld. Alexander Bain w 1846 roku używał taśm perforowanych do telegrafii. Charles Wheatstone (którego możecie kojarzyć z powodu jego mostka pomiarowego) w 1857 wykorzystał ten system do zapisywania, przechowywania i szybkiego przesyłania danych drogą telegraficzną. Wynalezione później dalekopisy używały taśm perforowanych i binarnego kodu Baudota zarówno do przechowywania kopii wiadomości, jak i do ich szybkiej transmisji.
W pierwszej połowie XX wieku głównym zastosowaniem kart i taśm perforowanych było przechowywanie, sortowanie i tabulacja danych i programowanie zautomatyzowanych maszyn przemysłowych. Naturalnym jest to, że były też używane przez systemy komputerowe. Zarówno IBM, jak i Remington Rand oferowały maszyny pozwalające odczytać karty i taśmy używane w ich systemach elektromechanicznych do wprowadzania danych do pamięci komputerowych, a także zapisu na taśmach, bębnach i dyskach magnetycznych. Obecnie nie spotyka się już systemów opartych lub wykorzystujących taśmy czy karty perforowane. Zwykle są to stare maszyny utrzymane w ruchu dlatego, że ich wymiana jest nieopłacalna lub/i kłopotliwa.
Pierwsze systemy odczytu były mechaniczne - bolec wpadał w otwór przemieszczając dołączoną do niego mechaniczną dźwignię, co wykonywało określoną czynność. W fisharmoniach otwierało to odpowiednie zawory. Inną opcją, równie popularną, był opisany wyżej odczyt elektromechaniczny. Dla zwiększenia prędkości odczytu wynaleziono też system elektroniczny wykorzystujący źródło światła i jego detektory. Nadal jednak karty czy taśma musiały być przesuwane mechanicznie, co spowalniało ten rodzaj pamięci. Z kolei do zapisu używano maszyn dziurkujących realizujących tę czynność mechanicznie (gdy informacje są wprowadzane ręcznie) lub elektromechanicznie (dla systemów automatycznych). Niską, choć bezpieczną prędkość przez lata równoważył też niski koszt nośnika.
Tu drobna ciekawostka: przetwarzanie wsadowe (batch processing) wzięło swoją nazwę i zasadę działania właśnie z wczesnych czasów informatyki, gdy komputery programowane były z pomocą kart i taśm perforowanych. Programy były dostarczane w formie stosu kart lub odcinków taśmy. Stosy były układane jeden na drugim w maszynie czytającej, taśmy zaś kopiowano na jedną, długą taśmę zawierającą wiele programów. Komputer kontrolował czytnik, więc mógł załadować program, wykonać go, wydrukować lub wydziurkować wynik i wczytać kolejny program do wykonania. Praca operatora ograniczała się do notowania błędów, zbierania wyników i ładowania nowych wsadów. Ludzie pracujący ze stosami kart nauczyli się, by z boku stosu rysować kilka kresek ołówkiem lub długopisem - karty nie były numerowane, więc przypadkowe rozsypanie stosu nie było aż taką tragedią.
Taśma pędzi bez pamięci
Komputer Colossus to fascynujący przykład maszyny zbudowanej do jednego celu: łamania szyfru Lorenza. Szyfr ten używał maszyny podobnej do Enigmy, gdzie naciśnięcie klawisza obracało pierwsze koło szyfrujące, a jego obrót napędzał kolejne, i tak dalej. Każde koło zawierało sekwencję binarną o zmiennej długości. Maszyna Lorenza szyfrowała łączność dalekopisową, więc pięć bitów kodu Baudota było szyfrowane równolegle przez wykonywanie operacji XOR, czyli alternatywy wykluczającej. Jeśli maszyny na obu końcach połączenia dalekopisowego zaczynały od tej samej pozycji startowej, jedna mogła zakodować wiadomość, a druga bezproblemowo ją rozkodować. Szyfr Lorenza był symetryczny i potencjalnie nie do złamania. Był tak bezpieczny, że używano go do łączności dyplomatycznej III Rzeszy oraz przez najwyższe szczeble ich dowództwa. Colossus łamał ten szyfr metodą statystyczną - szukał ustawień początkowych, przy których wybrane znaki pojawiają się częściej niż, by wynikało ze średniej arytmetycznej zaszyfrowanej wiadomości. Potrafił też dekodować sekwencję bitową używaną przez koła w maszynie Lorenza.
Colossus implementował algorytm dekodowania sprzętowo, a dane początkowe oraz zestaw operacji do wykonania ustawiane były przełącznikami i kablami, jak w ENIACu. Sekwencja bitów ustawionych w kołach maszyny Lorenza przechowywana była w serii tyratronów, czyli lamp elektronowych pracujących analogicznie do tyrystorów. Ponadto Colossus posiadał pięć liczników zliczających stopień spadku losowości dla poszczególnych strumieni bitowych kodu Baudota. Wiadomości do rozszyfrowania zapisane były na taśmie dziurkowanej stosowanej w dalekopisach. Taśma z wieloma wiadomościami była sklejana w formie pętli, i przemieszczała się z dużą prędkością przez optyczny czytnik. Programista/operator umieszczał taśmę w maszynie, ustawiał jakiś stan początkowy i minimalną wartość dla liczników, przy której maszyna kończyła pracę. Gdy maszyna stanęła, odczytywał bieżącą pozycję kół i zmieniał ich pozycje startowe oraz próg zatrzymania, aż w końcu trafiał na ustawienia, przy których losowy strumień bitów wytworzony przez szyfr Lorenza stawał się zrozumiałymi słowami dowództwa III Rzeszy.
Colossus nie miał tradycyjnych elementów procesora, program był przechowywany w formie fizycznych połączeń, zamiast rejestrów były liczniki resetowane przy każdym starcie, a jedyną prawdziwą pamięcią były tyratrony połączone w pierścienie by emulować koła maszyny Lorenza w formie elektronicznej. Mimo to Colossus działał sprawnie. Tak sprawnie, że z większości uzyskanych informacji nie można było skorzystać, bo by wyszło na jaw, że szyfr Lorenza został złamany. Podobny problem był z Enigmą, ale że była używana do szyfrowania rozkazów dla poszczególnych jednostek z godziny na godzinę, a nie całych planów strategicznych obejmujących tygodnie i miesiące działań, to łatwiej było ukryć wiedzę aliantów o ich treści jako "przypadkowe" natknięcie się na wroga.
Co tak klika? Pamięć elektromechaniczna
W latach 40stych powstało kilka komputerów elektromechanicznych. Przykładem może być komputer Z2 Konrada Zuse z 1939 roku. W 1941 roku powstał komputer Z3 zawierający 64 słowa pamięci o szerokości 22 bitów. Oba komputery używały przekaźników, co czyniło je głośnymi, powolnymi i prądożernymi. Z drugiej jednak strony przekaźniki psuły się rzadziej, niż lampy elektronowe komputerów w rodzaju ENIAC, EDSAC, Colossus czy Leo. Z3 posiadał 2000 przekaźników, z czego około 1400 realizowało funkcję pamięci.
Pamięć na przekaźniku realizuje się najczęściej łącząc styk normalnie otwarty do cewki przekaźnika, kotwę do jednego bieguna zasilania, a drugi biegun cewki do drugiego bieguna zasilania. Po podaniu impulsu zasilającego na cewkę, przekaźnik się załączy i będzie podtrzymywał swój stan, póki ma dostępne zasilanie. Można też użyć przekaźników bistabilnych, które funkcję podtrzymania realizują na drodze mechanicznej. Programy we wczesnych maszynach Zusego były zapisywane w formie taśmy perforowanej zrobionej ze starych, celuloidowych taśm filmowych 35mm.
Współczesnie amatorzy budują komputery przekaźnikowe, choć zwykle ograniczają się tylko do samej jednostki arytmetyczno-logicznej i do czterech lub ośmiu bitów. Komputery Zusego liczyły liczby zmiennoprzecinkowe 22-bitowe - celem było prowadzenie skomplikowanych obliczeń inżynieryjnych z zakresu aerodynamiki.
Pierwsza pamięć DRAM była próżna - lampa Williamsa–Kilburna
Freddi Williams i Tom Kilburn opracowali tę formę pamięci w roku 1946. W czasie II wojny światowej zdobyli doświadczenie pracując nad systemami radarowymi. By zrozumieć sposób działania tej pamięci, musimy zacząć od lamp oscyloskopowych, które były używane jako ekrany radarowe. Lampa taka składa się z trzech części: działa elektronowego, siatek odchylających wiązkę elektronów i ekranu pokrytego luminoforem. Działo elektronowe i towarzyszące mu siatki skupiające i przyspieszające wytwarzają wąski strumień elektronów. Strumień ten jest kontrolowany za pomocą siatek odchylających go w pionie i w poziomie. Jasność plamki reguluje się zmieniając prąd dostarczany do działa. Gdy elektrony uderzają i pokrytą luminoiforem powierzchnię, oddają swoją energię pobudzając luminofor do wyższego stanu energetycznego, gdy ten wraca do stanu pierwotnego, oddaje energię w formie emisji światła. W lampach radarowych i oscyloskopowych używa się luminoforów, które oddają energię powoli, dzięki czemu ślad wiązki elektronów jest dłużej widoczny.
Lampa Williamsa–Kilburna wykorzystuje uboczne zjawisko towarzyszące normalnej pracy lampy - gromadzenie się dodatniego ładunku na powierzchni lampy w miejscu, gdzie trafiła wiązka. Ta "studnia" pozytywnego ładunku istnieje tylko ułamki sekundy, ale z punktu widzenia komputera jest to wystarczająco długo. By "wymazać" ten ładunek wystarczy stworzyć nową tuż obok poprzedniej - ładunek zostanie przesunięty. Obecność ładunku była wykrywana za pomocą cienkiego, metalowego ekranu umieszczonego tuż przed frontem lampy. Adres ustalały napięcia sterujące siatkami odchylania. Odczyt bitu polegał na próbie jego ponownego zapisu - jeśli bit jest zapisany, żaden nowy ładunek nie powstanie w tym miejscu, przez co żaden prąd nie popłynie przez elektrodę czytającą. Ze względu na sposób działania odczyt bitu go kasował, co wymagało ponownego zapisu, analogicznie do pamięci ferrytowej, o której będzie poniżej. Do tego jeszcze pamięć musi być okresowo odświeżana, podobnie jak współczesna pamięć DRAM - robiły to obwody sterujące lampą niezależnie od procesora.
Lampy Williamsa–Kilburna oferowały pojemność od 256 do 2560 bitów, czyli maksymalnie 2,5kB. Były szybsze od wczesnych akustycznych linii opóźniających. Możliwy był też podgląd zawartości pamięci poprzez równoległe połączenie dwóch lamp: jedna miała założoną płytę detekcyjną, druga nie. Kropki oznaczały stan 1, kreski zaś stan 0. By przetestować potencjalne możliwości tej pamięci, wokół lampy Williamsa–Kilburna zbudowano komputer, Manchester Baby. Komputer ten miał słowo o długości 32 bitów, i 32 słowa pamięci, czyli 1024 bity. Komputer był zaprojektowany jako najprostsza możliwa maszyna, dlatego wykonywać mógł tylko operacje odejmowania i binarnej negacji. Jednym z pierwszych programów był algorytm szukający najwyższego dzielnika właściwego dla liczby 262144 (2 do osiemnastej potęgi). Program testował wszystkie liczby począwszy od 262144, operację dzielenia zaimplementowano w formie kolejnych odejmowań. Kod zawierał 17 instrukcji i po 52 minutach podał wynik: 131072. Program wykonał ~3,5 miliona operacji ze średnią prędkością komputera 1100 instrukcji na sekundę.
To tyle na teraz. Już teraz zapraszam was do części drugiej i trzeciej. Czekam też na Wasze komentarze. Czy chcielibyście zobaczyć praktyczny projekt czytnika kart perforowanych? Czy może artykuł o budowie komputera przekaźnikowego? Może sami coś takiego zbudowaliście, albo chcecie zbudować? Piszcie.
Słowo o architekturze i słowniczek pojęć
By lepiej zrozumieć zagadnienie pamięci, musimy najpierw poznać architekturę, a dokładniej to części składowe procesora. Nie będziemy zagłębiać się w tajniki najnowszych Ryzenów czy i9, ani w sekrety GPU. Spokojnie możemy sobie odpuścić tournée po ARMach, SoCach czy współczesnych mikrokontrolerach. Wystarczy Wam wiedzieć, że te same elementy są zarówno w nich, jak i w wielu pierwszych komputerach z lat 40stych i 50tych XX wieku. Ba, znajdziecie je nawet w opisie maszyny analitycznej Babbage'a.
Podstawowymi elementami niemal każdego procesora są: ALU, dekoder rozkazów, licznik rozkazów, rejestr rozkazów, układ kontrolny procesora i kilka rejestrów dodatkowych. ALU to inaczej jednostka arytmetyczno-logiczna, czyli element procesora, który wykonuje właściwą pracę. Do podstawowych operacji należą dodawanie, odejmowanie i porównywanie dwóch liczb binarnych. Bardziej rozbudowane układy potrafią przesuwać liczbę binarną w lewo lub w prawo, dodając z odpowiedniego końca zera, mnożyć dwie liczby, a czasem wykonywać nawet bardziej skomplikowane operacje, czasami na dużych zbiorach danych (tak działa wiele układów CISC, jak dawniejsze układy graficzne, DSP czy procesory komputerów osobistych od czasów Pentium). Dane te często znajdują się w rejestrach, czyli dedykowanych obwodach o pojemności najczęściej pojedyńczego słowa. Słowo to pojedyncza jednostka danych, jaką może przetworzyć ALU. Używam słów zamiast bajtów, bo wiele wczesnych procesorów miało słowa o nietypowych rozmiarach. Dla większości procesorów minimalna liczba rejestrów, to cztery: dwa rejestry wejściowe dla ALU, rejestr wyjściowy dla ALU i licznik rozkazów. Jest to specjalny rejestr, który wskazuje lokalizację w pamięci bieżącego rozkazu do wykonania. Dekoder rozkazów odczytuje ten rozkaz, umieszcza go w rejestrze rozkazów i steruje poszczególnymi elementami procesora, by ten rozkaz wykonać, po czym modyfikuje licznik rozkazów. Układ kontrolny odpowiada za kolejność wykonywania operacji w cyklu procesora: odczyt rozkazu z pamięci, załadowanie wartości do ALU, wykonanie operacji przez ALU, transfer danych do pamięci i przejście do następnego rozkazu.
No właśnie, pamięć. Poznaliśmy mimochodem pierwszy typ, czyli rejestry. Jest to najprostsza forma pamięci, zintegrowana w strukturze samego procesora do tego stopnia, że programista nie musi o tym myśleć, chyba że programuje w Assemblerze. Inne rodzaje pamięci zwykle są poza procesorem i dla jego pracy ich typy i budowa są mało istotne. Dlaczego? Ano dlatego, że typowy procesor czy mikroprocesor kontaktuje się ze światem za pomocą linii danych, które mogą łączyć się z wybranym przez rozkaz rejestrem, linii adresowych, które też mogą łączyć się z wybranym rejestrem, linii kierunku odczyt/zapis i linii, która sygnalizuje chęć odczytu lub zapisu. Pewnym wyjątkiem od tego podziału jest większość pierwszych komputerów, gdzie to dostępna pamięć dyktowała budowę procesora i jego prędkość działania.
Jeszcze słówko o architekturach. Są dwie podstawowe: harwardzka i von Neumanna. W architekturze harwardzkiej pamięć programu, czyli kolejne rozkazy do wykonania, jest oddzielona od pamięci, która przechowuje dane do przetworzenia. Wiele wczesnych komputerów miało taką budowę. Procesor w tym stylu ma oddzielne linie danych i adresowe dla pamięci programu i pamięci danych. W architekturze von Neumanna dane i instrukcje są w tej samej pamięci i używają tych samych linii do ich transferu, co spowalnia pracę (trzeba wykonać 2-3 transfery na każdy rozkaz), ale pozwala na łatwą samomodyfikację programu i oszczędza pamięć oraz liczbę linii do połączenia wszystkiego razem.
"Będziemy razem borować dziurki!" - karty i taśmy perforowane
Karty i taśmy perforowane wyprzedziły powstanie komputerów o ponad 200 lat. Basile Bouchon wykorzystał karty dziurkowane do automatyzacji pracy krosna, co pozwoliło na obniżenie kosztów produkcji tkanin. Joseph Marie Jacquard w 1804 roku zaprezentował automatyczną maszynę tkacką, w której wzory były programowane kartami dziurkowanymi. Przy okazji słowo "sabotaż" wywodzi się z tej ery: tkacze tracący zatrudnienie przez mechanizację produkcji wrzucali saboty (rodzaj obuwia) w tryby maszyn tkackich celem ich uszkodzenia.
Charles Babbage pracując nad swoimi maszynami zaproponował użycie kart dziurkowanych jako sposób na wprowadzanie danych i programów. Z kolei Jules Carpentier w 1881 roku zaprezentował pierwszą fisharmonię kontrolowaną przez zestaw kart dziurkowanych połączonych w taśmę. Jego system pozwalał muzykowi zagrać utwór, co automatycznie perforowało karty. Tak przygotowany utwór mógł być powielany mechanicznie. Wcześniej mechaniczne automaty grające wymagały, by dyski czy walce były wykonywane ręcznie, i do tego często z metalu.
Herman Hollerith opracował system zbierania informacji, wykonywania kart z tymi informacjami zakodowanymi oraz ich odczytu i zliczania wartości metodą elektromechaniczną, co zostało wykorzystane w czasie spisu powszechnego w USA w 1890 roku. Karty były umieszczane na łożu elektrod i dociskane od góry metalową płytką. Jeśli elektroda dotknęła płyty przez otwór w karcie, stosowny licznik rósł o jeden. Hollerith rozwinął swój pomysł i założył firmę produkującą maszyny sumujące, sortujące, perforujące i dekodujące karty dziurkowane. Firma ta istnieje do dzisiaj i jest znana pod nazwą IBM.
Taśmy perforowane rozwijały się równolegle. W 1842 Claude Seytre opatentował maszynę grającą na fortepianie sterowaną taśmą perforowaną. Do XX wieku pianole, czyli pianina automatyczne weszły do powszechnego użytku - można je zobaczyć zarówno w starych westernach, jak i we współczesnym serialu Westworld. Alexander Bain w 1846 roku używał taśm perforowanych do telegrafii. Charles Wheatstone (którego możecie kojarzyć z powodu jego mostka pomiarowego) w 1857 wykorzystał ten system do zapisywania, przechowywania i szybkiego przesyłania danych drogą telegraficzną. Wynalezione później dalekopisy używały taśm perforowanych i binarnego kodu Baudota zarówno do przechowywania kopii wiadomości, jak i do ich szybkiej transmisji.
W pierwszej połowie XX wieku głównym zastosowaniem kart i taśm perforowanych było przechowywanie, sortowanie i tabulacja danych i programowanie zautomatyzowanych maszyn przemysłowych. Naturalnym jest to, że były też używane przez systemy komputerowe. Zarówno IBM, jak i Remington Rand oferowały maszyny pozwalające odczytać karty i taśmy używane w ich systemach elektromechanicznych do wprowadzania danych do pamięci komputerowych, a także zapisu na taśmach, bębnach i dyskach magnetycznych. Obecnie nie spotyka się już systemów opartych lub wykorzystujących taśmy czy karty perforowane. Zwykle są to stare maszyny utrzymane w ruchu dlatego, że ich wymiana jest nieopłacalna lub/i kłopotliwa.
Pierwsze systemy odczytu były mechaniczne - bolec wpadał w otwór przemieszczając dołączoną do niego mechaniczną dźwignię, co wykonywało określoną czynność. W fisharmoniach otwierało to odpowiednie zawory. Inną opcją, równie popularną, był opisany wyżej odczyt elektromechaniczny. Dla zwiększenia prędkości odczytu wynaleziono też system elektroniczny wykorzystujący źródło światła i jego detektory. Nadal jednak karty czy taśma musiały być przesuwane mechanicznie, co spowalniało ten rodzaj pamięci. Z kolei do zapisu używano maszyn dziurkujących realizujących tę czynność mechanicznie (gdy informacje są wprowadzane ręcznie) lub elektromechanicznie (dla systemów automatycznych). Niską, choć bezpieczną prędkość przez lata równoważył też niski koszt nośnika.
Tu drobna ciekawostka: przetwarzanie wsadowe (batch processing) wzięło swoją nazwę i zasadę działania właśnie z wczesnych czasów informatyki, gdy komputery programowane były z pomocą kart i taśm perforowanych. Programy były dostarczane w formie stosu kart lub odcinków taśmy. Stosy były układane jeden na drugim w maszynie czytającej, taśmy zaś kopiowano na jedną, długą taśmę zawierającą wiele programów. Komputer kontrolował czytnik, więc mógł załadować program, wykonać go, wydrukować lub wydziurkować wynik i wczytać kolejny program do wykonania. Praca operatora ograniczała się do notowania błędów, zbierania wyników i ładowania nowych wsadów. Ludzie pracujący ze stosami kart nauczyli się, by z boku stosu rysować kilka kresek ołówkiem lub długopisem - karty nie były numerowane, więc przypadkowe rozsypanie stosu nie było aż taką tragedią.
Taśma pędzi bez pamięci
Komputer Colossus to fascynujący przykład maszyny zbudowanej do jednego celu: łamania szyfru Lorenza. Szyfr ten używał maszyny podobnej do Enigmy, gdzie naciśnięcie klawisza obracało pierwsze koło szyfrujące, a jego obrót napędzał kolejne, i tak dalej. Każde koło zawierało sekwencję binarną o zmiennej długości. Maszyna Lorenza szyfrowała łączność dalekopisową, więc pięć bitów kodu Baudota było szyfrowane równolegle przez wykonywanie operacji XOR, czyli alternatywy wykluczającej. Jeśli maszyny na obu końcach połączenia dalekopisowego zaczynały od tej samej pozycji startowej, jedna mogła zakodować wiadomość, a druga bezproblemowo ją rozkodować. Szyfr Lorenza był symetryczny i potencjalnie nie do złamania. Był tak bezpieczny, że używano go do łączności dyplomatycznej III Rzeszy oraz przez najwyższe szczeble ich dowództwa. Colossus łamał ten szyfr metodą statystyczną - szukał ustawień początkowych, przy których wybrane znaki pojawiają się częściej niż, by wynikało ze średniej arytmetycznej zaszyfrowanej wiadomości. Potrafił też dekodować sekwencję bitową używaną przez koła w maszynie Lorenza.
Colossus implementował algorytm dekodowania sprzętowo, a dane początkowe oraz zestaw operacji do wykonania ustawiane były przełącznikami i kablami, jak w ENIACu. Sekwencja bitów ustawionych w kołach maszyny Lorenza przechowywana była w serii tyratronów, czyli lamp elektronowych pracujących analogicznie do tyrystorów. Ponadto Colossus posiadał pięć liczników zliczających stopień spadku losowości dla poszczególnych strumieni bitowych kodu Baudota. Wiadomości do rozszyfrowania zapisane były na taśmie dziurkowanej stosowanej w dalekopisach. Taśma z wieloma wiadomościami była sklejana w formie pętli, i przemieszczała się z dużą prędkością przez optyczny czytnik. Programista/operator umieszczał taśmę w maszynie, ustawiał jakiś stan początkowy i minimalną wartość dla liczników, przy której maszyna kończyła pracę. Gdy maszyna stanęła, odczytywał bieżącą pozycję kół i zmieniał ich pozycje startowe oraz próg zatrzymania, aż w końcu trafiał na ustawienia, przy których losowy strumień bitów wytworzony przez szyfr Lorenza stawał się zrozumiałymi słowami dowództwa III Rzeszy.
Colossus nie miał tradycyjnych elementów procesora, program był przechowywany w formie fizycznych połączeń, zamiast rejestrów były liczniki resetowane przy każdym starcie, a jedyną prawdziwą pamięcią były tyratrony połączone w pierścienie by emulować koła maszyny Lorenza w formie elektronicznej. Mimo to Colossus działał sprawnie. Tak sprawnie, że z większości uzyskanych informacji nie można było skorzystać, bo by wyszło na jaw, że szyfr Lorenza został złamany. Podobny problem był z Enigmą, ale że była używana do szyfrowania rozkazów dla poszczególnych jednostek z godziny na godzinę, a nie całych planów strategicznych obejmujących tygodnie i miesiące działań, to łatwiej było ukryć wiedzę aliantów o ich treści jako "przypadkowe" natknięcie się na wroga.
Co tak klika? Pamięć elektromechaniczna
W latach 40stych powstało kilka komputerów elektromechanicznych. Przykładem może być komputer Z2 Konrada Zuse z 1939 roku. W 1941 roku powstał komputer Z3 zawierający 64 słowa pamięci o szerokości 22 bitów. Oba komputery używały przekaźników, co czyniło je głośnymi, powolnymi i prądożernymi. Z drugiej jednak strony przekaźniki psuły się rzadziej, niż lampy elektronowe komputerów w rodzaju ENIAC, EDSAC, Colossus czy Leo. Z3 posiadał 2000 przekaźników, z czego około 1400 realizowało funkcję pamięci.
Pamięć na przekaźniku realizuje się najczęściej łącząc styk normalnie otwarty do cewki przekaźnika, kotwę do jednego bieguna zasilania, a drugi biegun cewki do drugiego bieguna zasilania. Po podaniu impulsu zasilającego na cewkę, przekaźnik się załączy i będzie podtrzymywał swój stan, póki ma dostępne zasilanie. Można też użyć przekaźników bistabilnych, które funkcję podtrzymania realizują na drodze mechanicznej. Programy we wczesnych maszynach Zusego były zapisywane w formie taśmy perforowanej zrobionej ze starych, celuloidowych taśm filmowych 35mm.
Współczesnie amatorzy budują komputery przekaźnikowe, choć zwykle ograniczają się tylko do samej jednostki arytmetyczno-logicznej i do czterech lub ośmiu bitów. Komputery Zusego liczyły liczby zmiennoprzecinkowe 22-bitowe - celem było prowadzenie skomplikowanych obliczeń inżynieryjnych z zakresu aerodynamiki.
Pierwsza pamięć DRAM była próżna - lampa Williamsa–Kilburna
Freddi Williams i Tom Kilburn opracowali tę formę pamięci w roku 1946. W czasie II wojny światowej zdobyli doświadczenie pracując nad systemami radarowymi. By zrozumieć sposób działania tej pamięci, musimy zacząć od lamp oscyloskopowych, które były używane jako ekrany radarowe. Lampa taka składa się z trzech części: działa elektronowego, siatek odchylających wiązkę elektronów i ekranu pokrytego luminoforem. Działo elektronowe i towarzyszące mu siatki skupiające i przyspieszające wytwarzają wąski strumień elektronów. Strumień ten jest kontrolowany za pomocą siatek odchylających go w pionie i w poziomie. Jasność plamki reguluje się zmieniając prąd dostarczany do działa. Gdy elektrony uderzają i pokrytą luminoiforem powierzchnię, oddają swoją energię pobudzając luminofor do wyższego stanu energetycznego, gdy ten wraca do stanu pierwotnego, oddaje energię w formie emisji światła. W lampach radarowych i oscyloskopowych używa się luminoforów, które oddają energię powoli, dzięki czemu ślad wiązki elektronów jest dłużej widoczny.
Lampa Williamsa–Kilburna wykorzystuje uboczne zjawisko towarzyszące normalnej pracy lampy - gromadzenie się dodatniego ładunku na powierzchni lampy w miejscu, gdzie trafiła wiązka. Ta "studnia" pozytywnego ładunku istnieje tylko ułamki sekundy, ale z punktu widzenia komputera jest to wystarczająco długo. By "wymazać" ten ładunek wystarczy stworzyć nową tuż obok poprzedniej - ładunek zostanie przesunięty. Obecność ładunku była wykrywana za pomocą cienkiego, metalowego ekranu umieszczonego tuż przed frontem lampy. Adres ustalały napięcia sterujące siatkami odchylania. Odczyt bitu polegał na próbie jego ponownego zapisu - jeśli bit jest zapisany, żaden nowy ładunek nie powstanie w tym miejscu, przez co żaden prąd nie popłynie przez elektrodę czytającą. Ze względu na sposób działania odczyt bitu go kasował, co wymagało ponownego zapisu, analogicznie do pamięci ferrytowej, o której będzie poniżej. Do tego jeszcze pamięć musi być okresowo odświeżana, podobnie jak współczesna pamięć DRAM - robiły to obwody sterujące lampą niezależnie od procesora.
Lampy Williamsa–Kilburna oferowały pojemność od 256 do 2560 bitów, czyli maksymalnie 2,5kB. Były szybsze od wczesnych akustycznych linii opóźniających. Możliwy był też podgląd zawartości pamięci poprzez równoległe połączenie dwóch lamp: jedna miała założoną płytę detekcyjną, druga nie. Kropki oznaczały stan 1, kreski zaś stan 0. By przetestować potencjalne możliwości tej pamięci, wokół lampy Williamsa–Kilburna zbudowano komputer, Manchester Baby. Komputer ten miał słowo o długości 32 bitów, i 32 słowa pamięci, czyli 1024 bity. Komputer był zaprojektowany jako najprostsza możliwa maszyna, dlatego wykonywać mógł tylko operacje odejmowania i binarnej negacji. Jednym z pierwszych programów był algorytm szukający najwyższego dzielnika właściwego dla liczby 262144 (2 do osiemnastej potęgi). Program testował wszystkie liczby począwszy od 262144, operację dzielenia zaimplementowano w formie kolejnych odejmowań. Kod zawierał 17 instrukcji i po 52 minutach podał wynik: 131072. Program wykonał ~3,5 miliona operacji ze średnią prędkością komputera 1100 instrukcji na sekundę.
To tyle na teraz. Już teraz zapraszam was do części drugiej i trzeciej. Czekam też na Wasze komentarze. Czy chcielibyście zobaczyć praktyczny projekt czytnika kart perforowanych? Czy może artykuł o budowie komputera przekaźnikowego? Może sami coś takiego zbudowaliście, albo chcecie zbudować? Piszcie.
Cool? Ranking DIY