Jak powstawało K-202

Z MERA 400 wiki
Przejdź do nawigacji Przejdź do wyszukiwania

Andrzej Ziemkiewicz

Przedsięwzięcie

K-202 było przedsięwzięciem szczególnym jak na warunki polskie w tamtych czasach. Dzisiaj powiedzielibyśmy joint-venture, a wtedy była to umowa o współpracę zawarta pomiędzy Zjednoczeniem Przemysłu Maszynowego MERA, a dokładniej jego Biurem Handlu Zagranicznego METRONEX oraz dwoma firmami angielskimi: firmą handlową Data Loop i firmą elektroniczną MBMetals.

Inicjatorem był inż. Jacek Karpiński, któremu udało się namówić na to ówczesnego Ministra Przemysłu Maszynowego. Mówił, że chce zbudować minikomputer o nazwie K-202.

Sam pomysł takiej umowy wynikał z prostej obserwacji, że na Zachodzie nie brak ani pieniędzy, ani elementów, natomiast w Polsce brak pieniędzy i elementów, za to nie brak dobrze wyszkolonych inżynierów. Gdyby zatem udało się w Polsce stworzyć jakąś wysepkę czy enklawę kapitalizmu, to łącząc te dwie rzeczy można by osiągnąć sukces. Dziwne, że nikt wcześniej na to nie wpadł. Później Jacek Karpiński powiedział w wywiadzie jakiemuś dziennikarzowi, że jemu ten pomysł podsunął Stefan Bratkowski. No więc chwała im obu! Jak się później okazało, elementy dostarczane dla skonstruowania jednego egzemplarza maszyny kosztowały 1200-1500 dolarów, a zmontowana maszyna była sprzedawana za 5000 dolarów, czyli jako business-plan było to bardzo dochodowe przedsięwzięcie.

Przy Zakładach Produkcji Urządzeń Pomiarowych ERA we Włochach pod Warszawą utworzony został nowy Zakład Budowy Minikomputerów, Jacek Karpiński został mianowany dyrektorem i zaczął organizować zespół konstruktorów.

Założenia strategiczne

Pierwszym założeniem strategicznym Jacka Karpińskiego było, że ma to być minikomputer. Było to jednak mylące i wymaga wyjaśnienia. W tym czasie minikomputery były to 4- i 8-bitowe maleństwa. Nie to miał Karpiński na myśli. Zespołowi projektantów (którzy przecież musieli wiedzieć, co mają robić) powiedział, o co chodzi i podał swoją definicję minikomputera: "Minikomputer jest to komputer, który kosztuje mniej niż 10 tys. dolarów". Tak więc nie chodziło o 8-bitowe maleństwo, tylko o porządną maszynę, ale tanią.

Dlaczego więc Jacek używał terminu minikomputer? Nie wiem, może to był taki wybieg, aby nie nasuwać podejrzenia, że może to być konkurencja dla innych zakładów i że władze łatwiej to przełkną. W każdym razie termin jest nieadekwatny i ja bym wolał, żeby tego przedrostka "mini" nie używać. Przecież rówieśnika K-202, jakim było PDP-11 nikt nie nazywał minikomputerem, chociaż jego możliwości architektoniczne były dużo mniejsze niż K-202.

Drugie założenie strategiczne postawił Jacek zaraz przy pierwszym spotkaniu. Powiedział "Słuchajcie, robimy tę maszynę w kooperacji z angielskimi firmami i musi ona dać się sprzedawać na zachodzie. Do tego jest konieczne, aby wystawić ją na ekspozycji Olympia w Londynie w przyszłym roku (czyli za 8 miesięcy). Jeśli nie zdążymy, to rok później będzie już za późno, bo inni zajmą rynek". Miał oczywiście rację.

Oba te założenia miały duże konsekwencje. Jeśli maszyna miała być tania i zrobiona w 8 miesięcy, to znaczyło, że trzeba ją robić szybko i prosto, a wszystkie rozwiązania skomplikowane, wymagające zbyt dużo czasu lub zbyt drogie musiały być odłożone do innej okazji. Zresztą wszyscy traktowaliśmy ten projekt jako pierwszą wersję, po której zaraz zrobimy drugą, poprawioną i uzupełnioną. Tylko że ta druga wersja (Mera-400) i trzecia wersja (MX-16) były zrobione już bez udziału Jacka.

Założenia techniczne

Modularność

Założeniem było, że nie będzie różnych modeli maszyny: mały, średni, duży itd. Jeżeli użytkownik będzie chciał mieć większą konfigurację, to zostanie ona złożona z większej ilości standardowych modułów, ale moduły te będą zawsze te same niezależnie od wielkości konfiguracji.

Standardowe moduły

Przewidziane były 4 standardowe moduły systemu:

  • Procesor: 16-bitowy, wyposażony w arytmometr stało- i zmienno-przecinkowy;
  • Moduł pamięci operacyjnej: o adresacji słowowej i pojemności 16K, 32K lub 64K słów;
  • Kanał (kontroler) pamięciowy: dla transmisji z/do pamięci masowych (dyski, taśmy);
  • Kanał (kontroler) znakowy: dla urządzeń znakowych (terminale, drukarki, czytniki i perforatory taśmy papierowej itp.).

Później różne inne ośrodki zaczęły konstruować także swoje moduły, takie jak CAMAC i inne kontrolery dla celów automatyki.

Standardowe interface'y

Były przewidziane dwa standardowe interface'y:

  • Interface pamięciowy: standardowa szyna, poprzez którą są łączone procesory, moduły pamięci operacyjnej oraz kanały pamięciowe, mogące prowadzić samodzielnie transmisje blokowe między pamięcią operacyjną a pamięciami masowymi;
  • Interface znakowy: standardowa szyna, poprzez którą urządzenia znakowe są dołączane do procesora. Transmisja prowadzona jest przez procesor, znak po znaku.

Wstępna koncepcja

Wstępna koncepcja Jacka Karpińskiego zawierała schemat blokowy systemu oraz wstępną listę rozkazów. Schemat blokowy przedstawiony jest poniżej.

Wstępna koncepcja K-202 (teoretyczna konfiguracja max)

Koncepcja przedstawiona na rysunku powyżej wygląda bardzo ładnie i elegancko. Ale od tej koncepcji do projektu była jeszcze daleka droga. Należało odpowiedzieć na szereg pytań: Szyna pamięciowa, do której są dołączone procesor, moduły pamięci i kanały pamięciowe, na jakiej zasadzie ma działać? Ma ona być synchroniczna czy asynchroniczna? Jeśli synchroniczna, to synchronizowana jakim zegarem? Jeśli asynchroniczna, to w jaki sposób? Moduły pamięci: jak ma być zrobiona adresacja w modułach i w całej pamięci? Jak ma być robiona wirtualizacja pamięci? Dostęp do szyny: jak ma być zrobione rozwiązywanie konfliktów w dostępie, gdy dwa lub więcej modułów próbuje dostać się jednocześnie do szyny?

Te i inne problemy były rozwiązywane w trybie seminaryjnym. Początkowo każdego dnia rano Jacek Karpiński zwoływał zebranie robocze i podawał temat do dyskusji. Na ogół też (ale nie zawsze) proponował rozwiązanie i zaczynała się "burza mózgów". Każdy mógł się wypowiedzieć, chociaż tak naprawdę to Ela i ja mieliśmy najwięcej do powiedzenia, jako że mieliśmy już za sobą udział w projektowaniu 5 komputerów, więc mieliśmy największe doświadczenie. I nie zawsze też było przyjęte rozwiązanie proponowane przez Jacka.

Po iluś takich zebraniach wszystkie decyzje zostały podjęte i każdy zespół skupił się na projektowaniu swojej części.

Tak więc podsumowując, Jacek był autorem koncepcji, przedstawionej na schemacie powyżej. Nawiasem mówiąc, był to pierwszy i jedyny schemat, który wyszedł spod jego ręki. Rozwinięcie koncepcji było dziełem zbiorowym, dokonanym pod jego kierunkiem, a projekt poszczególnych modułów wykonywały poszczególne podzespoły. Do tego Jacek już w zasadzie nie mieszał się i zostawiał wolną rękę projektantom. Miał zaufanie do zespołu.

Pamięć

Organizacja pamięci była tematem jednego z pierwszych zebrań roboczych. Ponieważ tu Jacek miał pomysł zupełnie unikalny, więc dla jasności dobrze będzie pokazać, jak to było robione we wszystkich innych maszynach:

Klasyczna metoda wirtualizacji

Pamięć fizyczna maszyny jest jedno-wymiarowa i ciągła, reprezentowana na rysunku przez pionową oś z lewej strony, adresowana od 0 do maksymalnego adresu.

Każdy proces, utworzony i uruchomiony przez system operacyjny, musi mieć pamięć. Oczywiście niedopuszczalne jest, aby każdy proces mógł sobie buszować po pamięci fizycznej, tak jak chce, bo mógłby coś popsuć innemu procesowi.

Zatem każdy proces działa na segmencie pamięci wirtualnej, to jest na takiej pamięci, co do której proces sobie wyobraża, że ją ma, a która naprawdę nie istnieje. Jedyna istniejąca fizycznie pamięć to ta na pionowej osi z lewej strony. Każde odwołanie procesu do jego pamięci wirtualnej podlega translacji adresu, która przekształca adres wirtualny na adres pamięci fizycznej.

Rozwiązanie takie posiada zarówno wady jak zalety. Zacznijmy od zalet:

  • Możliwość dobrego wykorzystania pamięci fizycznej. Jak długo jest jeszcze wolny kawałek pamięci fizycznej, można utworzyć następny proces i przydzielić mu ten kawałek.
  • Możliwość utworzenia pamięci dzielonej. Jeden kawałek pamięci fizycznej można przypisać nie jednemu, ale kilku procesom, które mogą używać ten kawałek pamięci do wymiany informacji między sobą.

Wady tego rozwiązania:

  • Operacja translacji adresów nie jest za darmo. Wymaga użycia sumatora i wydłuża czas dostępu o czas przejścia adresu przez ten sumator.
  • Wymaga rozwiązania problemu ochrony dostępu pomiędzy procesami. Należy zapewnić, że proces nie wejdzie w obszar pamięci fizycznej innego procesu. Na ogół wymaga to zbudowania specjalnego układu, sprawdzającego przetranslowane adresy.

Organizacja pamięci, zaproponowana przez Jacka była zupełnie różna i przedstawia ją rysunek poniżej:

Wstępna koncepcja pamięci K-202

Tu proces w odwołaniach do pamięci używa również adresu wirtualnego, ale tym razem jest to adres istniejący fizycznie. Każdemu procesowi system operacyjny przydziela blok (segment) pamięci, który stanowi przestrzeń wirtualną procesu, ale przy odwołaniach do pamięci do adresu tego automatycznie dopisywany jest na najstarszych bitach numer bloku i razem stanowi to pełny adres logiczny, który jest zarazem adresem fizycznym pamięci.

To rozwiązanie posiada pewne wady:

  • Stopień wykorzystania pamięci. Jeżeli proces wykorzystuje tylko część przydzielonego mu bloku, to reszta pojemności tego bloku nie może być wykorzystana.
  • Nie da się utworzyć pamięci dzielonej.

Natomiast zalety są następujące:

  • Pełna ochrona pamięci pomiędzy procesami. Po prostu żaden proces nie może się dostać do pamięci innych procesów i to bez żadnych dodatkowych środków ochrony.
  • Niepotrzebna jest jakakolwiek translacja adresów. Nie ma straty czasu na jej wykonanie.
  • Koncepcja ta przystawała doskonale do naszych strategicznych założeń: szybko, prosto i tanio.

Toteż koncepcja ta od razu nam się spodobała, mimo że nie było to szczytowe osiągnięcie architektoniczne. Nie było żadnego stronicowania, a segmentacja nie była dynamiczna, bo segmenty (bloki) były stałe. No ale to przecież można będzie rozwinąć w następnej wersji, mówiliśmy sobie.

Na pamięć tę należy patrzeć jako na dwuwymiarową: jeden wymiar to numer bloku, a drugi to adres wewnątrz bloku.

Od razu tez pomyśleliśmy, że można to jeszcze ulepszyć. Jeżeli jest już pamięć dwuwymiarowa, to zróbmy z niej trójwymiarową. Inaczej mówiąc, zaproponowaliśmy dopisanie jeszcze jednego lub dwóch bitów do adresu i zapisywanie w nich numeru procesora. W ten sposób można będzie tworzyć konfiguracje wieloprocesorowe. Do koncepcji systemu modularnego dobrze to pasuje, bo jeśli użytkownik zechce zwiększyć moc obliczeniową systemu, to może dołączyć dodatkowy procesor. Jackowi ten pomysł się spodobał i w ten sposób powstała finalna koncepcja maszyny, pokazana na następnym rysunku:

Finalna koncepcja pamięci K-202

Każdy procesor ma swój prywatny zerowy blok pamięci, pozostałe bloki są blokami użytkowymi.

Później okazało się, że te cztery procesory to aż nadto, bo ograniczeniem na moc obliczeniową systemu zaczyna być przepustowość szyny pamięciowej i przy większej liczbie procesorów nie są one w pełni wykorzystane. Toteż nie zmontowano konfiguracji, zawierających więcej, niż dwa procesory.

Hand-shake

Tematem innego zebrania była sprawa sterowania szyną pamięciową: synchroniczne czy asynchroniczne?

Tu byliśmy zgodni z Jackiem: żadnego zegara taktującego. Sterowanie ma być asynchroniczne. Zresztą po projektach maszyn ZAM byliśmy do tego przyzwyczajeni. Jacek miał tu pomysł na odpowiedni hand-shake, czyli sekwencję sygnałów sterujących. Polegała ona na tym, że:

  • Klient np. procesor, jeżeli chciał sięgnąć do pamięci lub kanału pamięciowego, albo kanał pamięciowy, jeżeli chciał sięgnąć do pamięci, to po uzyskaniu dostępu do szyny pamięciowej, wysyłał na szynę adres i odpowiedni rozkaz;
  • Adresat polecenia przygotowywał żądaną informację i wysyłał ją na szynę danych, a gdy była już gotowa, to wysyłał na szynę sygnał OK;
  • Klient odczytywał informację, a następnie zdejmował rozkaz z szyny;
  • Adresat polecenia zdejmował wtedy informację z szyny danych i operacja była zakończona.

Przewidziany był również przypadek, gdy adresat polecenia nie mógł lub nie chciał go przyjąć (np. kanał pamięciowy prowadził właśnie transmisję i nie mógł przyjąć nowego polecenia). Wtedy zamiast wysłać sygnał OK, wysyłał sygnał NOK (Not-OK), który kończył natychmiast operację i powodował w programie przejście do innej gałęzi. Spostrzegliśmy też, że jeśli zdarzy się odwołanie do nieistniejącego adresu, to żaden adresat nie przyśle sygnału OK ani NOK i sterowanie utknie. Dodaliśmy więc jeszcze time-out, nieco dłuższy niż czas reakcji najwolniejszego modułu w systemie. Po jego przekroczeniu operacja była kończona natychmiast i procesor otrzymywał sygnał przerwania typu "Nieistniejący adres".

Ten system działał doskonale i umożliwiał dołączanie elementów o rozmaitych szybkościach działania. Każdy moduł pracował tak szybko, jak tylko potrafił, bez tracenia czasu na oczekiwanie sygnału zegarowego.

Przydział szyny pamięciowej

Tematem jeszcze innego zebrania był problem dostępu. Co zrobić, gdy dwóch lub więcej klientów chce jednocześnie dostać się do szyny pamięciowej?

Jacek proponował, aby każdy klient wysyłał adres na szynę adresową, a następnie sprawdzał, czy na szynie jest ten właśnie adres. Jeżeli nie jest jedynym kandydatem, to na szynie będzie suma logiczna adresów, różna od każdego z nich. Wtedy każdy klient ma wycofać się i za jakiś czas ma spróbować ponownie. Jest to sposób podobny do tego, jaki używa się w sieci Ethernet.

Nam się ten pomysł nie podobał. Po pierwsze, to wycofywanie się i próbowanie ponowne (być może kilka razy) jest stratą czasu. Po drugie nie jest to metoda pewna. Jeżeli zdarzy się, że zbiór jedynek w jednym z tych adresów będzie podzbiorem drugiego, to ten, który ma więcej jedynek, nie wykryje konfliktu. Jacek się nie upierał (nigdy się nie upierał dlatego tylko, że pomysł był jego). Spytał, jak więc chcemy to zrobić.

Musimy zrobić układ przydziału szyny, który będzie przydzielał szynę jednemu tylko klientowi naraz. Nie może to być układ skupiony (na przykład w procesorze), bo trzeba będzie prowadzić z niego indywidualne przewody do każdego modułu. Musi to być zatem układ rozproszony, zaprojektowany tak, aby każdy moduł dołączał się do szyny wraz ze swoim fragmentem tego układu.

My w tym momencie nie mogliśmy się tym zająć, bo mieliśmy inne pilne rzeczy, ale nasz przyjaciel dr Andrzej Karczmarewicz zaofiarował się zrobić projekt. Zrobił to doskonale i układ działał świetnie.

Procesor

Już w czasie projektowania procesora okazało się, że uda nam się tak go "upchać", że w module procesora (czyli w jednej obudowie) oprócz samego procesora zmieści się także jeden blok pamięci (blok systemowy o numerze 0) oraz jeden kanał znakowy. Schemat tego modułu przedstawia rysunek poniżej:

Moduł procesora K-202

Symbolem CPU oznaczaliśmy procesor (Central Processing Unit).

Finalna koncepcja

Tak więc ustalona została finalna koncepcja, przedstawiona poniżej:

Finalna koncepcja K-202 (teoretyczna konfiguracja max)

Architektura maszyny była najbogatsza ze wszystkich maszyn tej klasy w tamtym czasie, zwłaszcza jeśli chodzi o wielkość pamięci operacyjnej. Jednej rzeczy nie dopatrzyliśmy jednak, a mianowicie organizacji kanałów znakowych. Wzięliśmy ją ze wstępnej koncepcji Jacka, nie zauważając dwóch słabych punktów:

  • Szyna znakowa była prywatną szyną procesora. Jeśli do jednego z procesorów było dołączone urządzenie, np. drukarka, to inne procesory nie miały do tej drukarki dostępu. Problem ten był możliwy do obejścia, bo przewidziane były środki do komunikacji miedzy-procesorowej, więc ten drugi procesor mógł poprosić, żeby mu ten pierwszy coś wydrukował, niemniej było to kłopotliwe.
  • Kanały znakowe nie miały dostępu do pamięci, a to wykluczało DMA (Direct Memory Access). Tego niestety nie da się obejść. Każdy znak z urządzenia musi być odczytany przez procesor (znak po znaku). Byłoby lepiej, gdyby procesor mógł wysłać do kanału polecenie takie, jak np. "przeczytaj wiersz tekstu z urządzenia i zapisz go do pamięci od wskazanego adresu". Usterka ta została poprawiona w maszynie Mera-400.

Reszta projektu, a następnie montaż prototypu przebiegały już bez specjalnych problemów.

Dyskusja

K-202 była jak na tamte czasy maszyną bardzo nowoczesną. Modularność i niewielka ilość modułów podstawowych umożliwiały łatwe zestawianie konfiguracji o dużej różnorodności i rozmaitej wielkości. Była bardzo szybka, a żadna inna maszyna tej klasy nie mogła konkurować z K-202 pod względem pojemności pamięci. Nawet PDP-11 (przynajmniej ten model, który powstał w tym samym mniej więcej czasie) mógł mieć tylko 64KB pamięci.

Asynchroniczny hand-shake i rozproszony układ przydziału szyny działały doskonale, dzięki czemu zainstalowanie w konfiguracji nowego modułu wymagało wyłącznie dołączenia modułu do szyny.

Maszyna miała też pewne słabości, wynikające z tego, że czas naglił i trzeba ją było zrobić prosto, tanio i szybko. Należały do nich: brak stronicowania pamięci, statyczna segmentacja, brak stosu systemowego i nie najlepiej trafiona architektura kanałów znakowych. Wszystkie te słabe punkty miały być poprawione w następnej wersji, a zostało to zrobione w maszynie Mera-400.

Dalszy rozwój

Po odejściu Jacka Karpińskiego koncepcja K-202 była nadal rozwijana przez zespól.

Mera-400

Mera-400 nie jest co prawda tematem tego opracowania, ponieważ jednak może być widziana jako kontynuacja K-202, więc warto pokazać przynajmniej jedną z rzeczy, które zostały w niej rozwinięte, a mianowicie dynamiczną segmentację i stronicowanie pamięci.

Pamięć MERA-400 - stan początkowy

W stanie początkowym, czyli po włączeniu zasilania, pamięć logiczna posiada tylko blok 0 (systemowy). Nie ma żadnych logicznych bloków użytkowych. Cała pamięć fizyczna stanowi pulę wolnych stron, które nie reagują jednak na żadne odwołania do pamięci.

Pamięć MERA-400 - jeden blok użytkowy (proces)

Gdy system operacyjny chce utworzyć i uruchomić proces użytkowy, to dynamicznie tworzy dla niego segment pamięci wirtualnej. W tym celu bierze odpowiednią ilość stron z puli wolnych stron i przyporządkowuje każdej z nich numer bloku i najstarsze bity adresu wewnątrz bloku. Od tej chwili strony te reagują na polecenia odczytu i zapisu do pamięci.

Pamięć MERA-400 - dwa bloki użytkowe (procesy)

Przy tworzeniu następnego procesu system operacyjny postępuje podobnie. Użyte wolne strony nie muszą być wszystkie w tym samym bloku fizycznym. Gdy pula wolnych stron w bloku fizycznym wyczerpie się, system operacyjny bierze strony z następnego bloku, jak to jest pokazane na rysunku.

Zauważmy, że jest tu możliwe tworzenie pamięci dzielonej. Nawet w systemie wielo-programowym w danym momencie aktywny jest tylko jeden proces naraz. Zatem przy przełączaniu kontekstu system operacyjny może stronę pamięci dzielonej przełączać z jednego procesu do drugiego.

MX-16

Po zaprzestaniu produkcji Mery-400 przez zakłady ERA zespól nadal kontynuował rozwój maszyny pod nazwą MX-16 w firmie polonijnej AMEPOL. Rozwój ten dotyczył głównie dwóch aspektów:

  • Większą inteligencję uzyskały kontrolery i jednostki sterujące urządzeń, dzięki zbudowaniu ich jako mikrokomputery oparte na procesorze Intel 8085;
  • Dzięki pojawieniu się na rynku scalonych układów pamięciowych o dużej pojemności, zbudowano moduły pamięci operacyjnej o pojemności 1M, a następnie 2M słów w jednym module fizycznym.

O maszynach Mera-400 i MX-16 wspominam tu tylko bardzo krótko, ponieważ są przedmiotem osobnego opracowania.