Burroughs duże systemy - Burroughs large systems

Burroughs Large Systems Group produkowany rodzinę dużych 48-bitowych komputerów mainframe z wykorzystaniem maszyna stosowa zestawów instrukcji gęstymi sylab . Pierwszą maszyną w rodzinie był B5000 w 1961 roku. Został zoptymalizowany pod kątem kompilacji programów ALGOL 60 bardzo dobrze, przy użyciu kompilatorów jednoprzebiegowych. Przekształcił się w B5500. Kolejne duże przeprojektowania obejmują linię B6500/B6700 i jej następców, a także oddzielną linię B8500.

W latach siedemdziesiątych firma Burroughs Corporation została podzielona na trzy działy o bardzo różnych architekturach linii produktów dla systemów biznesowych klasy high-end, mid-range i entry-level. Linia produktów każdego działu wyrosła z innej koncepcji optymalizacji zestawu instrukcji komputera dla poszczególnych języków programowania. „Burroughs Large Systems” odnosi się do wszystkich tych dużych linii produktów razem, w przeciwieństwie do średnich systemów zoptymalizowanych pod kątem języka COBOL (B2000, B3000 i B4000) lub małych systemów o elastycznej architekturze (B1000).

Tło

Założona w 1880 roku firma Burroughs była najstarszą nieprzerwanie działającą firmą komputerową ( Eliott Brothers została założona przed Burroughs, ale nie produkowała urządzeń komputerowych w XIX wieku). Pod koniec lat pięćdziesiątych jej sprzęt komputerowy ograniczał się do elektromechanicznych maszyn księgowych, takich jak Sensimatic . Nie miał nic do konkurowania ze swoimi tradycyjnymi rywalami IBM i NCR , którzy zaczęli produkować komputery na większą skalę, lub z niedawno założonym Univacem . W 1956 kupili firmę zewnętrzną i przemianowali jej projekt na B205.

Pierwsza wewnętrznie opracowana maszyna Burroughsa, B5000, została zaprojektowana w 1961 roku, a Burroughs starał się zająć późnym wejściem na rynek strategią zupełnie innego projektu opartego na najbardziej zaawansowanych koncepcjach obliczeniowych dostępnych w tamtym czasie. Chociaż architektura B5000 jest martwa, zainspirowała B6500 (i kolejne B6700 i B7700). Komputery korzystające z tej architektury były nadal w produkcji, jako serwery Unisys ClearPath Libra, które działają na rozwiniętej, ale kompatybilnej wersji systemu operacyjnego MCP wprowadzonego po raz pierwszy w B6700. Trzecia i największa linia, B8500, nie odniosła komercyjnego sukcesu. Oprócz zastrzeżonego projektu procesora CMOS , Unisys używa również procesorów Intel Xeon i uruchamia systemy operacyjne MCP , Microsoft Windows i Linux na swoich serwerach Libra; stosowanie niestandardowych chipów zostało stopniowo wyeliminowane, a do 2018 r. serwery Libra były przez kilka lat ściśle towarowe dla Intela.

B5000

Pierwszy członek pierwszej serii, B5000, został zaprojektowany w 1961 roku przez zespół pod kierownictwem Roberta (Boba) Bartona . Miał niezwykłą architekturę. Został wymieniony przez informatyka Johna Masheya jako jedna z architektur, które najbardziej podziwia. „Zawsze myślałem, że jest to jeden z najbardziej innowacyjnych przykładów łączenia sprzętu i oprogramowania, jaki widziałem, znacznie wyprzedzający swoje czasy”. B5000 został zastąpiony przez B5500 (który używał dysków zamiast pamięci bębnowej) i B5700 (który umożliwiał klastrowanie wielu procesorów wokół dysku współdzielonego). Chociaż nie było następcy B5700, linia B5000 w dużym stopniu wpłynęła na konstrukcję B6500, a Burroughs przeniósł Master Control Program ( MCP ) do tej maszyny.

Cechy

  • Cały kod automatycznie powraca (rys. 4.5 z monografii ACM pokazuje w skrócie dlaczego): programiści nie muszą robić nic więcej, aby jakikolwiek kod w dowolnym języku był rozłożony na procesory, niż używać tylko dwóch pokazanych prostych prymitywów. Wynika to z tych głównych cech tej architektury:
  • Obsługa asymetrycznego przetwarzania wieloprocesowego (master/slave)
  • Obsługa innych języków, takich jak COBOL
  • Potężna manipulacja ciągami
  • Próba bezpiecznej architektury uniemożliwiającej nieautoryzowany dostęp do danych lub zakłócenia operacji
  • Wczesne wykrywanie błędów wspierające rozwój i testowanie oprogramowania
  • Komercyjna pamięć wirtualna implementacji, poprzedzona jedynie Atlasem Ferranti .</ref><
  • Pierwszy segmentowy model pamięci
  • Następcy nadal istnieją w maszynach Unisys ClearPath/MCP

Projekt systemu

B5000 był niezwykły w tamtych czasach, ponieważ architektura i zestaw instrukcji zostały zaprojektowane z uwzględnieniem potrzeb oprogramowania. Było to duże odejście od ówczesnego projektowania systemu komputerowego, w którym procesor i jego zestaw instrukcji były projektowane, a następnie przekazywane ludziom zajmującym się oprogramowaniem.

B5000, B5500 i B5700 w trybie Word mają dwa różne tryby adresowania, w zależności od tego, czy wykonuje program główny (SALF wyłączony), czy podprogram (SALF włączony). W przypadku programu głównego pole T w sylabie wywołania operandu lub wywołania deskryptora odnosi się do tabeli odniesienia programu (PRT). W przypadku podprogramów typ adresowania zależy od trzech najwyższych bitów T i od Mark Stack FlipFlop (MSFF), jak pokazano w B5x00 Relative Addressing .

B5x00 Adresowanie względne
SALF T0
A38
T1
A39
T2
A40
MSFF Baza Zawartość Znak indeksu Indeks
Bity
Maksymalny
indeks
WYŁĄCZONY - - - - r Adres PRT + T 0-9
A 38-47
1023
NA WYŁĄCZONY - - - r Adres PRT + T 1-9
A 39-47
511
NA NA WYŁĄCZONY - WYŁĄCZONY F Adres ostatniego RCW lub MSCW na stosie + T 2-9
A 40-47
255
NA NA WYŁĄCZONY - NA (R+7) Rejestr F z MSCW w PRT+7 + T 2-9
A 40-47
255
NA NA NA WYŁĄCZONY - C Adres aktualnego słowa polecenia + T 3-9
A 41-47
127
NA NA NA NA WYŁĄCZONY F Adres ostatniego RCW lub MSCW na stosie - T 3-9
A 41-47
127
NA NA NA NA NA (R+7) Rejestr F z MSCW w PRT+7 - T 3-9
A 41-47
127
Uwagi:

Wsparcie językowe

B5000 został zaprojektowany do obsługi wyłącznie języków wysokiego poziomu. Było to w czasie, gdy takie języki dopiero zyskiwały na znaczeniu w przypadku FORTRAN, a następnie COBOL . FORTRAN i COBOL były przez niektórych uważane za słabsze języki, jeśli chodzi o nowoczesne techniki oprogramowania, więc przyjęto nowszy, w większości niewypróbowany język, ALGOL-60 . Dialektem ALGOL wybranym dla B5000 był Elliott ALGOL , po raz pierwszy zaprojektowany i wdrożony przez CAR Hoare na Elliott 503 . Było to praktyczne rozszerzenie ALGOL z instrukcjami I/O (które ALGOL zignorował) i potężnymi instrukcjami przetwarzania łańcuchów. Słynny wykład Hoare'a o nagrodzie Turinga dotyczył tego tematu.

W ten sposób B5000 opierał się na bardzo potężnym języku. Donald Knuth wcześniej wdrożył ALGOL 58 na wcześniejszej maszynie Burroughsa podczas trzech miesięcy swojej letniej przerwy i był peryferyjnie zaangażowany w projektowanie B5000 jako konsultant. Wielu skreśliło ALGOL, błędnie wierząc, że języki wysokiego poziomu nie mogą mieć takiej samej mocy jak asembler, a tym samym nie zdając sobie sprawy z potencjału ALGOL jako języka programowania systemów.

Kompilator Burroughs ALGOL był bardzo szybki — to zrobiło wrażenie na holenderskim naukowcu Edsger Dijkstra, kiedy przedstawił program, który miał zostać skompilowany w zakładzie B5000 Pasadena. Jego talia kart została skompilowana niemal natychmiast i od razu chciał mieć kilka maszyn dla swojej uczelni, Eindhoven University of Technology w Holandii. Kompilator był szybki z kilku powodów, ale głównym powodem było to, że był to kompilator jednoprzebiegowy . Wczesne komputery nie miały wystarczającej ilości pamięci do przechowywania kodu źródłowego, więc kompilatory (a nawet asemblery) zwykle musiały czytać kod źródłowy więcej niż raz. Składnia Burroughs ALGOL, w przeciwieństwie do języka oficjalnego, wymaga, aby każda zmienna (lub inny obiekt) była zadeklarowana przed użyciem, więc możliwe jest napisanie kompilatora ALGOL, który odczytuje dane tylko raz. Koncepcja ta ma głębokie implikacje teoretyczne, ale pozwala również na bardzo szybkie kompilowanie. Duże systemy Burroughs mogły kompilować się tak szybko, jak odczytywały kod źródłowy z kart perforowanych i miały najszybsze czytniki kart w branży.

Potężny kompilator Burroughs COBOL był również kompilatorem jednoprzebiegowym i równie szybkim. Program COBOL na 4000 kart został skompilowany tak szybko, jak czytniki 1000 kart na minutę były w stanie odczytać kod. Program był gotowy do użycia, gdy tylko karty przeszły przez czytnik.

Rysunek 4.5 Z monografii ACM w odnośnikach. Elliot Organick 1973.

B6500 i B7500

B6500 (dostawa w 1969) i B7500 były pierwszymi komputerami z jedynej linii systemów Burroughs, które przetrwały do ​​dnia dzisiejszego. Chociaż inspirowali się B5000, mieli zupełnie nową architekturę. Wśród najważniejszych różnic były:

B6700 i B7700

Wśród innych klientów były wszystkie pięć nowozelandzkich uniwersytetów w 1971 roku.

B8500

Linia B8500 wywodzi się z D825, komputera wojskowego inspirowanego B5000.

B8500 został zaprojektowany w latach 60. jako próba połączenia projektów B5500 i D825. W systemie zastosowano monolityczne układy scalone z magnetyczną pamięcią cienkowarstwową . Architektura wykorzystywała 48-bitowe słowo, stos i deskryptory, takie jak B5500, ale nie była reklamowana jako kompatybilna w górę. B8500 nigdy nie można było uruchomić niezawodnie, a projekt został anulowany po 1970 roku, nie dostarczając nigdy ukończonego systemu.

Historia

Centralna koncepcja pamięci wirtualnej pojawiła się w projektach Atlasu Ferranti i komputera Rice Institute , a centralne koncepcje deskryptorów i architektury tagowanej pojawiły się w projektach komputera Rice Institute pod koniec lat pięćdziesiątych. Jednak nawet jeśli te projekty miały bezpośredni wpływ na Burroughsa, architektury B5000, B6500 i B8500 bardzo różniły się od architektury Atlasa i maszyny do ryżu; bardzo się od siebie różnią.

Pierwszym z dużych systemów Burroughs był B5000. Zaprojektowany w 1961 roku, był komputerem drugiej generacji, wykorzystującym dyskretną logikę tranzystorową i pamięć z rdzeniem magnetycznym . Pierwszymi maszynami, które zastąpiły architekturę B5000, były B6500 i B7500. Kolejne maszyny podążały za trendami rozwoju sprzętu, aby ponownie wdrożyć architektury w nowej logice w ciągu następnych 25 lat, z seriami B5500, B6500, B5700, B6700, B7700, B6800, B7800 i wreszcie z serii Burroughs A. Po fuzji, w której Burroughs nabył Sperry Corporation i zmienił nazwę na Unisys , firma kontynuowała rozwój nowych maszyn opartych na MCP CMOS ASIC . Maszyny te to Libra 100 do Libra 500, z Libra 590 ogłoszonym w 2005 roku. Późniejsze Libra, w tym 590, zawierają również procesory Intel Xeon i mogą obsługiwać architekturę dużych systemów Burroughs w emulacji, a także na procesorach MCP CMOS . Nie jest jasne, czy Unisys będzie kontynuował rozwój nowych układów ASIC MCP CMOS.

Burroughs (1961-1986)
B5000 1961 układ początkowy, komputer (tranzystorowy) drugiej generacji
B5500 1964 3x poprawa prędkości
B6500 1969 Komputer III generacji (układy scalone), do 4 procesorów
B5700 1971 nowa nazwa dla B5500
B6700 1971 nowa nazwa/poprawka błędu dla B6500
B7700 1972 szybszy procesor, pamięć podręczna dla stosu, do 8 requesterów (procesory we/wy lub centralne) w jednej lub dwóch partycjach.
B6800 1977? pamięć półprzewodnikowa, architektura NUMA
B7800 1977? pamięć półprzewodnikowa, szybsza, do 8 requesterów (procesory we/wy lub centralne) w jednej lub dwóch partycjach.
B5900 1980? pamięć półprzewodnikowa, architektura NUMA . Maksymalnie 4 procesory B5900 powiązane z pamięcią lokalną i wspólną pamięcią globalną II (tm)
B6900 1979? pamięć półprzewodnikowa, architektura NUMA . Maksymalnie 4 procesory B6900 powiązane z pamięcią lokalną i wspólną pamięcią globalną (tm)
B7900 1982? pamięć półprzewodnikowa, szybsza, pamięć podręczna kodu i danych, architektura NUMA ,

1-2 HDU (I/O), 1-2 punkty dostępowe, 1-4 procesory, Miękka implementacja pamięci NUMA pozwoliła procesorom na przemieszczanie się z obszaru pamięci do obszaru pamięci.

A9/A10 1984 Klasa B6000, pierwszy procesor potokowy ze średniej półki, pojedynczy procesor (podwójny w A10), pierwszy obsługujący eMode Beta (rozszerzone adresowanie pamięci)
A12/A15 1985 Klasa B7000, ponownie zaimplementowana w specjalnie zaprojektowanych macierzach bramek Motorola ECL MCA1, a następnie MCA2 , pojedynczy procesor pojedynczy HDU (A12) 1–4 procesor, 1–2 HDU (A15)
Unisys (1986-obecnie)
Mikro A 1989 desktopowy "mainframe" z jednoukładowym procesorem SCAMP.
Clearpath HMP NX 4000 1996? ??
Clearpath HMP NX 5000 1996? ??
Clearpath HMP LX 5000 1998 Implementuje duże systemy Burroughs tylko w emulacji ( procesory Xeon )
Waga 100 2002? ??
Waga 200 200? ??
Waga 300 200? ??
Waga 400 200? ??
Waga 500 2005? np. Waga 595
Waga 600 2006? ??
Waga 700 2010 np. Waga 750

Podstawowe linie sprzętu

Projektowanie, rozwój i produkcja sprzętu i oprogramowania były podzielone między dwie główne lokalizacje, w hrabstwie Orange w Kalifornii i na przedmieściach Filadelfii . Pierwsza fabryka dużych systemów, która opracowała B5000 i B5500, znajdowała się w Pasadenie w Kalifornii, ale została przeniesiona do City of Industry w Kalifornii , gdzie opracowała B6500. Lokalizacja Orange County, która znajdowała się w zakładzie w Mission Viejo w Kalifornii, ale czasami obejmowała obiekty w pobliskim Irvine i Lake Forest , była odpowiedzialna za mniejszą linię B6x00, podczas gdy operacje na Wschodnim Wybrzeżu, z siedzibą w Tredyffrin w Pensylwanii , obsługiwały większa linia B7x00. Wszystkie maszyny z obu linii były w pełni kompatybilne obiektowo, co oznacza, że ​​program skompilowany na jednym mógł być wykonywany na innym. Nowsze i większe modele miały instrukcje, które nie były obsługiwane w starszych i wolniejszych modelach, ale sprzęt, napotykając nierozpoznaną instrukcję, wywoływał funkcję systemu operacyjnego, która ją interpretowała. Inne różnice obejmują sposób obsługi przełączania procesów i operacji we/wy oraz funkcje konserwacji i zimnego startu. Większe systemy obejmowały sprzętowe planowanie procesów i bardziej wydajne moduły wejścia/wyjścia, a także bardziej funkcjonalne procesory konserwacyjne. Kiedy modele Bxx00 zostały zastąpione modelami z serii A, różnice zostały zachowane, ale nie można ich już łatwo zidentyfikować na podstawie numeru modelu.

ALGOL

Burroughs ALGOL
Paradygmaty Wieloparadygmat : proceduralny , imperatywny , ustrukturyzowany
Rodzina ALGOL
Zaprojektowany przez John McClintock, inni
Deweloper Burroughs Corporation
Po raz pierwszy pojawiły się 1962 ; 59 lat temu ( 1962 )
Platforma Burroughs duże systemy
OS Burroughs MCP
Wpływem
ALGOL 60
Pod wpływem
ESPOL , MCP , NEWP

Duże systemy Burroughs implementują architekturę stosu opartą na ALGOL . B5000 był pierwszym systemem opartym na stosie.

Chociaż B5000 został specjalnie zaprojektowany do obsługi ALGOL, był to tylko punkt wyjścia. Inne języki zorientowane na biznes, takie jak COBOL, były również dobrze obsługiwane, w szczególności przez potężne operatory ciągów, które zostały uwzględnione w rozwoju szybkich kompilatorów.

ALGOL używany w B5000 jest rozszerzonym podzbiorem ALGOL. Zawiera potężne instrukcje manipulacji ciągami, ale wyklucza pewne konstrukcje ALGOL, w szczególności nieokreślone parametry formalne. Mechanizm DEFINE służy podobnemu celowi jak #defines z C, ale jest w pełni zintegrowany z językiem, a nie preprocesorem. Typ danych EVENT ułatwia koordynację procesów, a bloki ON FAULT umożliwiają obsługę błędów programu.

Poziom użytkownika ALGOL nie obejmuje wielu niepewnych konstrukcji wymaganych przez system operacyjny i inne oprogramowanie systemowe. Dwa poziomy rozszerzeń językowych zapewniają dodatkowe konstrukcje: ESPOL i NEWP do pisania MCP i ściśle powiązanego oprogramowania oraz DCALGOL i DMALGOL do dostarczania bardziej szczegółowych rozszerzeń dla określonych rodzajów oprogramowania systemowego.

ESPOL i NEWP

Pierwotnie system operacyjny B5000 MCP został napisany w rozszerzeniu rozszerzonego języka ALGOL o nazwie ESPOL (Executive Systems Programming Oriented Language). Został on zastąpiony w połowie lat 70. przez język o nazwie NEWP . Chociaż NEWP prawdopodobnie oznaczało po prostu „nowy język programowania”, legendy otaczają nazwę. Powszechna (być może apokryficzna) historia w Burroughs w tamtym czasie sugerowała, że ​​pochodzi z „ No Executive Washroom Privileges ”. Inna historia jest taka, że ​​około 1976 r. John McClintock z Burroughs (inżynier oprogramowania rozwijający NEWP) nazwał język „NEWP” po tym, jak ponownie zapytano go „czy ma już nazwę”: odpowiadając „nieeeee”, przyjął to jako Nazwa. NEWP również był podzbiorem rozszerzenia ALGOL, ale był bezpieczniejszy niż ESPOL i zrezygnował z niektórych rzadko używanych złożoności ALGOL. W rzeczywistości wszystkie niebezpieczne konstrukcje są odrzucane przez kompilator NEWP, chyba że blok jest specjalnie oznaczony, aby zezwalać na te instrukcje. Takie oznaczenie bloków zapewnia wielopoziomowy mechanizm ochrony.

Programy NEWP zawierające niebezpieczne konstrukcje są początkowo niewykonywalne. Administrator bezpieczeństwa systemu jest w stanie "błogosławić" takie programy i uczynić je wykonywalnymi, ale zwykli użytkownicy nie są w stanie tego zrobić. (Nawet „uprzywilejowani użytkownicy”, którzy zwykle mają zasadniczo uprawnienia roota, mogą nie być w stanie tego zrobić w zależności od konfiguracji wybranej przez witrynę.) Podczas gdy NEWP może być używany do pisania ogólnych programów i ma wiele funkcji zaprojektowanych dla dużych projektów oprogramowania , nie obsługuje wszystkiego, co robi ALGOL.

NEWP posiada szereg udogodnień umożliwiających realizację projektów oprogramowania na dużą skalę, takich jak system operacyjny, w tym nazwane interfejsy (funkcje i dane), grupy interfejsów, moduły i supermoduły. Moduły grupują dane i funkcje razem, umożliwiając łatwy dostęp do danych jako globalnych w module. Interfejsy umożliwiają modułowi importowanie i eksportowanie funkcji i danych. Supermoduły umożliwiają grupowanie modułów.

DCALGOL i systemy kontroli wiadomości (MCS)

Drugi pośredni poziom bezpieczeństwa między kodem systemu operacyjnego (w NEWP) a programami użytkownika (w ALGOL) dotyczy programów oprogramowania pośredniego , które są napisane w DCALGOL (komunikacja danych ALGOL). Służy do odbierania i wysyłania komunikatów, które usuwają komunikaty z kolejek wejściowych i umieszczają je w kolejkach do obsługi przez inne procesy w systemie. Middleware, takie jak COMS (wprowadzone około 1984 roku), odbierać wiadomości z całego sieci i wysyła te wiadomości do obsługi specyficznych procesów lub do MCS (Message Control System), takie jak Candé ( „ C ommand I E dit” środowisko programistyczne programu).

MCS to elementy oprogramowania, na które warto zwrócić uwagę — kontrolują one sesje użytkowników i zapewniają śledzenie stanu użytkownika bez konieczności uruchamiania procesów na użytkownika, ponieważ pojedynczy stos MCS może być współużytkowany przez wielu użytkowników. Równoważenie obciążenia można również osiągnąć na poziomie MCS. Na przykład, mówiąc, że chcesz obsłużyć 30 użytkowników na stos, w którym to przypadku, jeśli masz od 31 do 60 użytkowników, masz dwa stosy, od 61 do 90 użytkowników, trzy stosy itp. Daje to maszynom B5000 dużą przewagę wydajności w serwer, ponieważ nie musisz uruchamiać innego procesu użytkownika, a tym samym tworzyć nowego stosu za każdym razem, gdy użytkownik podłącza się do systemu. W ten sposób można efektywnie obsługiwać użytkowników (niezależnie od tego, czy wymagają stanu, czy nie) za pomocą systemów MCS. Systemy MCS stanowią również podstawę przetwarzania transakcji na dużą skalę.

MCS rozmawiał z zewnętrznym koprocesorem, DCP (Datacomm Control Processor). Był to 24-bitowy minikomputer z konwencjonalną architekturą rejestrów i sprzętową obsługą we/wy do obsługi tysięcy zdalnych terminali. DCP i B6500 komunikowały się za pomocą komunikatów w pamięci, zasadniczo w dzisiejszych terminach jako pakiety, a MCS przetwarzał te komunikaty po stronie B6500. We wczesnych latach DCP miał asembler (Dacoma), program użytkowy o nazwie DCPProgen napisany w B6500 ALGOL. Później kompilator NDL (Network Definition Language) wygenerował kod DCP i NDF (plik definicji sieci). Dla każdego rodzaju instrukcji DCP była jedna funkcja ALGOL, a jeśli wywołasz tę funkcję, na wyjście zostaną wyemitowane odpowiednie bity instrukcji DCP. Program DCP był programem ALGOL zawierającym tylko długą listę wywołań tych funkcji, po jednym dla każdej instrukcji asemblera. Zasadniczo ALGOL zachowywał się jak przejście makr w asemblerze makr. Pierwszym przebiegiem był kompilator ALGOL; drugi przebieg polegał na uruchomieniu programu wynikowego (na B6500), który następnie emitował plik binarny dla DCP.

DMALGOL i bazy danych

Innym wariantem ALGOL jest DMALGOL (zarządzanie danymi ALGOL). DMALGOL jest rozszerzeniem ALGOL do kompilowania oprogramowania bazodanowego DMSII z plików opisów baz danych utworzonych przez kompilator DASDL (Data Access and Structure Definition Language). Projektanci i administratorzy baz danych kompilują opisy baz danych w celu wygenerowania kodu DMALGOL dostosowanego do określonych tabel i indeksów. Administratorzy nigdy nie muszą sami pisać DMALGOL. Zwykłe programy poziomu użytkownika uzyskują dostęp do bazy danych za pomocą kodu napisanego w językach aplikacji, głównie ALGOL i COBOL, rozszerzonego o instrukcje bazy danych i dyrektywy przetwarzania transakcji. Najbardziej godną uwagi cechą DMALGOL są jego mechanizmy przetwarzania wstępnego do generowania kodu do obsługi tabel i indeksów.

Przetwarzanie wstępne DMALGOL obejmuje zmienne i pętle oraz może generować nazwy na podstawie zmiennych czasu kompilacji. Umożliwia to dostosowywanie znacznie wykraczające poza to, co można zrobić za pomocą urządzeń do przetwarzania wstępnego, które nie mają pętli.

DMALGOL służy do zapewniania dostosowanych procedur dostępu do baz danych DMSII . Po zdefiniowaniu bazy danych przy użyciu języka dostępu do danych i struktury definicji (DASDL), schemat jest tłumaczony przez preprocesor na dostosowane procedury dostępu DMALGOL, a następnie kompilowany. Oznacza to, że w przeciwieństwie do innych implementacji DBMS, często nie ma potrzeby stosowania specyficznego dla bazy danych kodu if/then/else w czasie wykonywania. W latach 70. to „dopasowanie” było szeroko stosowane w celu zmniejszenia ilości kodu i czasu wykonania. W późniejszych latach stał się znacznie rzadziej używany, częściowo dlatego, że precyzyjne dostrajanie pamięci i szybkości na niskim poziomie stało się mniej krytyczne, a częściowo dlatego, że wyeliminowanie przetwarzania wstępnego uprościło kodowanie, a tym samym umożliwiło ważniejsze optymalizacje. DMALGOL zawierał czasowniki takie jak „znajdź”, „zablokuj”, „przechowuj”. Uwzględniono również czasowniki „begintransaction” i „endtransaction”, rozwiązując sytuację impasu, gdy wiele procesów uzyskiwało dostęp i aktualizowało te same struktury.

Roy Guck z Burroughs był jednym z głównych twórców DMSII .

W późniejszych latach, gdy rozmiar kodu kompilatora był mniej istotny, większość konstrukcji przetwarzania wstępnego została udostępniona na poziomie użytkownika ALGOL. Tylko niebezpieczne konstrukcje i bezpośrednie przetwarzanie pliku opisu bazy danych pozostają ograniczone do DMALGOL.

Architektura stosu

W wielu wczesnych systemach i językach programistom często mówiono, aby ich procedury nie były zbyt małe. Wywołania procedur i zwroty były kosztowne, ponieważ trzeba było wykonać szereg operacji, aby utrzymać stos. B5000 został zaprojektowany jako maszyna stosowa – wszystkie dane programu z wyjątkiem tablic (które zawierają ciągi znaków i obiekty) były przechowywane na stosie. Oznaczało to, że operacje stosu zostały zoptymalizowane pod kątem wydajności. Jako maszyna zorientowana na stos nie ma rejestrów adresowalnych przez programistę.

Wielozadaniowość jest również bardzo wydajna na liniach B5000 i B6500. Istnieją szczegółowe instrukcje dotyczące wykonywania przełączników procesowych:

B5000, B5500, B5700
Zainicjuj P1 (IP1) i Zainicjuj P2 (IP2)
B6500, B7500 i następcy
MVST (przenieś stos).

Każdy stos i skojarzona z nim tabela referencyjna programu (PRT) reprezentuje proces (zadanie lub wątek), a zadania mogą zostać zablokowane w oczekiwaniu na żądania zasobów (co obejmuje oczekiwanie na uruchomienie procesora, jeśli zadanie zostało przerwane z powodu wywłaszczania wielozadaniowości). Programy użytkownika nie mogą wydawać adresów IP1, IP2 ani MVST, a w systemie operacyjnym jest tylko jedno miejsce, w którym to się dzieje.

Tak więc przełączanie procesów przebiega mniej więcej tak – proces żąda zasobu, który nie jest natychmiast dostępny, może odczytu rekordu pliku z bloku, którego aktualnie nie ma w pamięci, lub zegar systemowy wyzwolił przerwanie. Kod systemu operacyjnego jest wprowadzany i uruchamiany na szczycie stosu użytkownika. Wyłącza liczniki procesów użytkownika. Bieżący proces jest umieszczany w odpowiedniej kolejce dla żądanego zasobu lub w kolejce gotowości oczekującej na procesor, jeśli jest to wywłaszczający przełącznik kontekstu. System operacyjny określa pierwszy proces w kolejce gotowości i wywołuje instrukcję move_stack, która uaktywnia proces na początku kolejki gotowości.

Szybkość i wydajność stosu

Wydajność stosu została uznana za niską w porównaniu do architektur opartych na rejestrach, na przykład taka architektura została uwzględniona i odrzucona dla System/360 . Jednym ze sposobów na zwiększenie szybkości systemu jest utrzymywanie danych jak najbliżej procesora. W stosie B5000 zostało to zrobione przez przypisanie dwóch górnych pozycji stosu do dwóch rejestrów A i B. Większość operacji jest wykonywana na tych dwóch najwyższych pozycjach stosu. Na szybszych maszynach starszych niż B5000 więcej stosu może być przechowywanych w rejestrach lub pamięci podręcznej w pobliżu procesora.

W ten sposób projektanci obecnych następców systemów B5000 mogą optymalizować w dowolnej najnowszej technice, a programiści nie muszą dostosowywać swojego kodu, aby działał szybciej – nie muszą nawet rekompilować, chroniąc w ten sposób inwestycje w oprogramowanie. Wiadomo, że niektóre programy działają od lat po wielu uaktualnieniach procesorów. Takie przyspieszenie jest ograniczone na maszynach opartych na rejestrach.

Inną kwestią dotyczącą szybkości promowaną przez projektantów RISC było to, że szybkość procesora jest znacznie większa, jeśli wszystko jest na jednym chipie. Był to ważny moment w latach 70., kiedy bardziej złożone architektury, takie jak B5000, wymagały zbyt wielu tranzystorów, aby zmieściły się na jednym chipie. Jednak obecnie tak nie jest i każda następna maszyna B5000 mieści się teraz na jednym chipie, a także na technikach wspierających wydajność, takich jak pamięć podręczna i potoki instrukcji.

W rzeczywistości linia następców B5000 z serii A obejmowała pierwszy jednoukładowy komputer główny, Micro-A z późnych lat 80-tych. Ten układ „mainframe” (o nazwie SCAMP od jednoukładowego procesora Mainframe z serii A) był osadzony na wtykowej płycie PC opartej na procesorach Intela.

Jak programy mapują się na stos?

Oto przykład mapowania programów na strukturę stosu

begin
   — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
   — This is lexical level 2 (level zero is reserved for the operating system and level 1 for code segments).
   — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
   
   — At level 2 we place global variables for our program.
   
   integer i, j, k;
   real f, g;
   array a [0:9];
   
   procedure p (real p1, p2);
      value p1;     — p1 passed by value, p2 implicitly passed by reference.
      begin
         — — — — — — — — — — — — — — — — — —
         — This block is at lexical level 3
         — — — — — — — — — — — — — — — — — —
         real r1, r2;
r2 := p1 * 5; p2 := r2; — This sets g to the value of r2 p1 := r2; — This sets p1 to r2, but not f — Since this overwrites the original value of f in p1 it might be a — coding mistake. Some few of ALGOL's successors therefore insist that — value parameters be read only – but most do not. if r2 > 10 then begin — — — — — — — — — — — — — — — — — — — — — — — — — — — — — A variable declared here makes this lexical level 4 — — — — — — — — — — — — — — — — — — — — — — — — — — — — integer n;
— The declaration of a variable makes this a block, which will invoke some — stack building code. Normally you won't declare variables here, in which — case this would be a compound statement, not a block. ... <== sample stack is executing somewhere here. end; end; ..... p (f, g); end.

Każda ramka stosu odpowiada poziomowi leksykalnemu w bieżącym środowisku wykonawczym. Jak widać, poziom leksykalny to statyczne zagnieżdżanie tekstowe programu, a nie dynamiczne zagnieżdżanie wywołań. Reguły widoczności ALGOL, języka zaprojektowanego dla kompilatorów jednoprzebiegowych, oznaczają, że tylko zmienne zadeklarowane przed bieżącą pozycją są widoczne w tej części kodu, stąd wymóg deklaracji forward. Widoczne są wszystkie zmienne zadeklarowane w otaczających blokach. Innym przypadkiem jest to, że zmienne o tej samej nazwie mogą być deklarowane w blokach wewnętrznych, które skutecznie ukrywają zmienne zewnętrzne, które stają się niedostępne.

Zagnieżdżanie leksykalne jest statyczne, niezwiązane z zagnieżdżaniem wykonywania z rekurencją itp., więc bardzo rzadko można znaleźć procedurę zagnieżdżoną na więcej niż pięć poziomów w głąb i można by argumentować, że takie programy byłyby słabo skonstruowane. Maszyny B5000 umożliwiają zagnieżdżanie do 32 poziomów. Może to powodować trudności dla niektórych systemów, które generowały źródło Algola jako wyjście (dostosowane do rozwiązania jakiegoś specjalnego problemu), jeśli metoda generowania często zagnieżdża procedurę w procedurze.

Procedury

Procedury można wywoływać na cztery sposoby – normalny, wywołanie, przetwarzanie i uruchomienie.

Normalne wywołanie wywołuje procedurę w normalny sposób, w jaki każdy język wywołuje procedurę, zawieszając procedurę wywołującą do czasu powrotu wywołanej procedury.

Wezwanie mechanizm wywołuje procedurę jako współprogram. Współprogramy mają zadania partnerskie, w których kontrola jest wyraźnie przekazywana między zadaniami za pomocą instrukcji CONTINUE. Są to procesy synchroniczne.

Proces mechanizm wywołuje procedurę asynchronicznego zadania i w tym przypadku oddzielny stos jest ustawiony począwszy od poziomu słownikowego procedury przetwarzania. Jako zadanie asynchroniczne nie ma kontroli nad dokładnym terminem przekazywania kontroli między zadaniami, w przeciwieństwie do współprogramów. Przetwarzana procedura nadal ma dostęp do otaczającego środowiska i jest to bardzo wydajny mechanizm IPC (Inter Process Communication). Ponieważ dwa lub więcej zadań ma teraz dostęp do wspólnych zmiennych, zadania muszą być zsynchronizowane, aby zapobiec wyścigom, co jest obsługiwane przez typ danych EVENT, w którym procesy mogą CZEKAĆ na zdarzenie, dopóki nie zostaną spowodowane przez inny współpracujący proces. ZDARZENIA pozwalają również na synchronizację wzajemnego wykluczania poprzez funkcje PROCURE i LIBERATE. Jeśli z jakiegoś powodu zadanie potomne umrze, zadanie wywołujące może być kontynuowane – jeśli jednak umrze proces nadrzędny, wszystkie procesy potomne zostaną automatycznie zakończone. Na komputerze z więcej niż jednym procesorem procesy mogą działać jednocześnie. Ten mechanizm EVENT jest podstawowym elementem umożliwiającym przetwarzanie wieloprocesowe oprócz wielozadaniowości.

Uruchom typ wywołania

Ostatnim typem wywołania jest prowadzony . Uruchamia procedurę jako niezależne zadanie, które może być kontynuowane po zakończeniu procesu źródłowego. Z tego powodu proces potomny nie może uzyskać dostępu do zmiennych w środowisku rodzica, a wszystkie parametry przekazywane do wywoływanej procedury muszą być wywołane według wartości.

W ten sposób Burroughs Extended ALGOL miał niektóre z funkcji przetwarzania wieloprocesowego i synchronizacji późniejszych języków, takich jak Ada . Wykorzystał wbudowaną w sprzęt obsługę procesów asynchronicznych.

Procedury inline

Ostatnią możliwością jest to, że procedura może być zadeklarowana INLINE, to znaczy, gdy kompilator widzi odwołanie do niej, kod procedury jest generowany inline, aby zaoszczędzić narzut wywołania procedury; najlepiej to zrobić dla małych fragmentów kodu. Funkcje wbudowane są podobne do sparametryzowanych makr, takich jak C #defines, z tą różnicą, że nie występują problemy z parametrami, które można uzyskać w przypadku makr. Ta funkcja jest dostępna w NEWP.

Połączenia asynchroniczne

W przykładowym programie używane są tylko normalne wywołania, więc wszystkie informacje będą na jednym stosie. W przypadku wywołań asynchronicznych stos zostanie podzielony na wiele stosów, aby procesy współdzieliły dane, ale działały asynchronicznie.

Wyświetl rejestry

Optymalizacja sprzętowa stosu polega na zapewnieniu rejestrów D (lub „wyświetlania”). Są to rejestry wskazujące początek każdej wywoływanej ramki stosu. Rejestry te są aktualizowane automatycznie w miarę wchodzenia i wychodzenia z procedur i nie są dostępne dla żadnego oprogramowania. Istnieją 32 rejestry D, co ogranicza do 32 poziomów zagnieżdżenia leksykalnego.

Zastanówmy się, jak uzyskalibyśmy dostęp do zmiennej globalnej poziomu leksykalnego 2 (D[2]) z poziomu leksykalnego 5 (D[5]). Załóżmy, że zmienna jest oddalona o 6 słów od podstawy poziomu leksykalnego 2. Jest więc reprezentowana przez parę adresów (2, 6). Jeśli nie mamy rejestrów D, musimy spojrzeć na słowo kontrolne u podstawy ramki D[5], które wskazuje na ramkę zawierającą środowisko D[4]. Następnie patrzymy na słowo kontrolne u podstawy tego środowiska, aby znaleźć środowisko D[3] i kontynuujemy w ten sposób, aż prześledzimy wszystkie linki z powrotem do wymaganego poziomu leksykalnego. To nie jest ta sama ścieżka, co droga powrotna przez procedury, które zostały wywołane w celu dotarcia do tego punktu. (Architektura utrzymuje zarówno stos danych, jak i stos wywołań w tej samej strukturze, ale używa słów kontrolnych, aby je odróżnić).

Jak widać, jest to dość nieefektywne, aby uzyskać dostęp do zmiennej. W przypadku rejestrów D rejestr D[2] wskazuje podstawę środowiska leksykalnego poziomu 2, a wszystko, co musimy zrobić, aby wygenerować adres zmiennej, to dodać jej przesunięcie od podstawy ramki stosu do adresu podstawowego ramki w rejestr D. (Istnieje wydajny operator wyszukiwania list połączonych LLLU, który może przeszukiwać stos w powyższy sposób, ale podejście rejestrów D nadal będzie szybsze.) Dzięki rejestrom D dostęp do jednostek w środowiskach zewnętrznych i globalnych jest równie wydajny jako dostęp do zmiennych lokalnych.

D Tag Data                — Address couple, Comments
register
| 0        | n          | (4, 1) The integer n (declared on entry to a block, not a procedure)
|-----------------------|
| D[4]==>3 | MSCW       | (4, 0) The Mark Stack Control Word containing the link to D[3].
|=======================|
| 0        | r2         | (3, 5) The real r2
|-----------------------|
| 0        | r1         | (3, 4) The real r1
|-----------------------|
| 1        | p2         | (3, 3) A SIRW reference to g at (2,6)
|-----------------------|
| 0        | p1         | (3, 2) The parameter p1 from value of f 
|-----------------------|
| 3        | RCW        | (3, 1) A return control word
|-----------------------|
| D[3]==>3 | MSCW       | (3, 0) The Mark Stack Control Word containing the link to D[2].
|=======================|
| 1        | a          | (2, 7) The array a  ======>[ten word memory block]
|-----------------------|
| 0        | g          | (2, 6) The real g 
|-----------------------|
| 0        | f          | (2, 5) The real f 
|-----------------------|
| 0        | k          | (2, 4) The integer k 
|-----------------------|
| 0        | j          | (2, 3) The integer j 
|-----------------------|
| 0        | i          | (2, 2) The integer i
|-----------------------|
| 3        | RCW        | (2, 1) A return control word
|-----------------------|
| D[2]==>3 | MSCW       | (2, 0) The Mark Stack Control Word containing the link to the previous stack frame.
|=======================| — Stack bottom

Gdybyśmy wywołali procedurę p jako współprogram lub instrukcję procesu, środowisko D[3] stałoby się oddzielnym stosem opartym na D[3]. Oznacza to, że procesy asynchroniczne nadal mają dostęp do środowiska D[2], co wynika z kodu programu ALGOL. Idąc o krok dalej, zupełnie inny program może wywołać kod innego programu, tworząc ramkę stosu D[3] wskazującą na środowisko D[2] innego procesu na szczycie własnego stosu procesów. W jednej chwili zmienia się cała przestrzeń adresowa ze środowiska wykonawczego kodu, sprawiając, że środowisko D[2] na własnym stosie procesów nie jest bezpośrednio adresowalne, a zamiast tego środowisko D[2] w innym stosie procesów jest bezpośrednio adresowalne. W ten sposób realizowane są wywołania biblioteczne. Przy takim wywołaniu krzyżowym kod wywołujący i kod wywoływany mogą nawet pochodzić z programów napisanych w różnych językach źródłowych i być kompilowane przez różne kompilatory.

Środowiska D[1] i D[0] nie występują w stosie bieżącego procesu. Środowisko D[1] to słownik segmentów kodu, który jest współdzielony przez wszystkie procesy uruchamiające ten sam kod. Środowisko D[0] reprezentuje jednostki eksportowane przez system operacyjny.

Ramki stosu w rzeczywistości nie muszą nawet istnieć w stosie procesów. Ta funkcja była używana wcześnie do optymalizacji plików we/wy, FIB (blok informacji o plikach) był połączony z rejestrami wyświetlania w D[1] podczas operacji we/wy. Na początku lat dziewięćdziesiątych ta zdolność została zaimplementowana jako funkcja językowa jako BLOK STRUKTURALNY oraz – w połączeniu z technologią biblioteczną – jako BLOK POŁĄCZENIA. Możliwość łączenia struktury danych z zakresem adresów rejestru wyświetlania zaimplementowana orientacja obiektów. Tak więc B5000 faktycznie używał formy orientacji obiektowej na długo przed tym, zanim ten termin został kiedykolwiek użyty.

W innych systemach kompilator może zbudować swoją tablicę symboli w podobny sposób, ale ostatecznie wymagania dotyczące pamięci zostaną zebrane, a kod maszynowy zostanie napisany tak, aby używał płaskich adresów pamięci 16-bitowych lub 32-bitowych, a nawet 64-bitowych. Te adresy mogą zawierać cokolwiek, tak że zapis pod niewłaściwy adres może coś uszkodzić. Zamiast tego dwuczęściowy schemat adresowania został zaimplementowany sprzętowo. Na każdym poziomie leksykalnym zmienne były umieszczane w miejscach przesunięć w górę od podstawy stosu poziomu, zwykle zajmując jedno słowo – zmienne podwójnej precyzji lub złożone zmienne zajmowałyby dwa. Tablice nie były przechowywane w tym obszarze, był tylko deskryptor jednego słowa dla tablicy. Tak więc na każdym poziomie leksykalnym całkowite zapotrzebowanie na pamięć nie było duże: dziesiątki, setki lub kilka tysięcy w skrajnych przypadkach, na pewno nie liczba wymagająca 32 bitów lub więcej. I rzeczywiście, zostało to odzwierciedlone w postaci instrukcji VALC (wywołanie wartości), która ładowała operand na stos. Ten kod operacyjny miał długość dwóch bitów, a pozostałe bity bajtu zostały połączone z kolejnym bajtem, aby uzyskać czternastobitowe pole adresowania. Wykonywany kod byłby na pewnym poziomie leksykalnym, powiedzmy szóstym: oznaczało to, że tylko poziomy leksykalne od zera do sześciu były poprawne, a więc potrzebne były tylko trzy bity, aby określić pożądany poziom leksykalny. W ten sposób część adresowa operacji VALC zarezerwowała tylko trzy bity do tego celu, przy czym pozostała część jest dostępna do odwoływania się do jednostek na tym i niższych poziomach. Głęboko zagnieżdżona procedura (a więc na wysokim poziomie leksykalnym) miałaby mniej bitów dostępnych do identyfikacji jednostek: od poziomu szesnastego w górę potrzeba byłoby pięciu bitów, aby określić wybór poziomów 0–31, pozostawiając dziewięć bitów do identyfikacji nie więcej niż pierwszy 512 jednostek na dowolnym poziomie leksykalnym. Jest to znacznie bardziej zwarte niż adresowanie jednostek przez ich dosłowny adres pamięci w 32-bitowej przestrzeni adresowej. Co więcej, tylko kody operacji VALC ładowały dane: kody operacji ADD, MULT i tak dalej nie miały adresowania, pracując całkowicie na najwyższych elementach stosu.

O wiele ważniejsze jest to, że ta metoda oznaczała, że ​​wiele błędów dostępnych dla systemów wykorzystujących adresowanie płaskie nie mogło wystąpić, ponieważ były one po prostu niewypowiedziane nawet na poziomie kodu maszynowego. Zadanie nie miało możliwości uszkodzenia pamięci używanej przez inne zadanie, ponieważ nie miało możliwości rozwinięcia swojego adresu. Przesunięcia z określonego rejestru D byłyby sprawdzane przez sprzęt względem ramki stosu: nieuczciwe wartości byłyby przechwytywane. Podobnie w zadaniu deskryptor tablicy zawierał informacje o granicach tablicy, więc każda operacja indeksowania była sprawdzana przez sprzęt: inaczej mówiąc, każda tablica tworzyła własną przestrzeń adresową. W każdym razie znakowanie wszystkich słów pamięci zapewniało drugi poziom ochrony: błędnie skierowane przypisanie wartości mogło trafić tylko do lokalizacji przechowującej dane, a nie do lokalizacji zawierającej wskaźnik lub deskryptor tablicy itp., a już na pewno nie lokalizacja przechowująca kod maszynowy.

Pamięć macierzowa

Tablice nie były przechowywane w pamięci w sposób ciągły z innymi zmiennymi, każda z nich miała własną przestrzeń adresową, która została zlokalizowana za pomocą deskryptora. Mechanizm dostępu polegał na obliczeniu na stosie zmiennej indeksu (która w związku z tym miała pełen potencjał zakresu liczb całkowitych, a nie tylko czternastu bitów) i użycie jej jako przesunięcia w przestrzeni adresowej tablicy, ze sprawdzaniem granic zapewnianym przez sprzęt. Jeśli długość tablicy przekroczy 1024 słowa, zostanie ona podzielona na segmenty, a indeks zostanie przekonwertowany na indeks segmentu, a przesunięcie na indeksowany segment. W przypadku ALGOL tablica wielowymiarowa wykorzystywałaby wiele poziomów takiego adresowania. Dla odniesienia do A(i,j), pierwszy indeks byłby w tablicy deskryptorów, jeden deskryptor dla każdego wiersza A, który to wiersz byłby następnie indeksowany przez j jak dla tablicy jednowymiarowej, i tak dla wyższych wymiarów. Sprawdzanie sprzętu pod kątem znanych granic wszystkich indeksów tablicy zapobiegłoby błędom indeksowania.

FORTRAN uważa jednak, że wszystkie tablice wielowymiarowe są równoważne tablicy jednowymiarowej o tym samym rozmiarze, a dla tablicy wielowymiarowej stosuje się prostą arytmetykę liczb całkowitych do obliczenia przesunięcia, w którym element A(i,j,k) byłby znaleziony w tym pojedynczym sekwencja. Jednowymiarowa równoważna tablica, prawdopodobnie podzielona na segmenty, jeśli jest wystarczająco duża, byłaby wtedy dostępna w taki sam sposób jak jednowymiarowa tablica w ALGOL. Chociaż dostęp poza tą tablicą byłby uniemożliwiony, nieprawidłowa wartość jednego indeksu w połączeniu z odpowiednio nieprawidłową wartością innego indeksu może nie skutkować naruszeniem granic tablicy z pojedynczą sekwencją; innymi słowy, indeksy nie były sprawdzane indywidualnie.

Ponieważ pamięć tablicy nie była ograniczona z każdej strony przez pamięć dla innych elementów, system mógł łatwo „zmienić rozmiar” tablicy — chociaż zmiana liczby wymiarów była wykluczona, ponieważ kompilatory wymagały, aby wszystkie odniesienia miały taką samą liczbę wymiarów. W przypadku ALGOL umożliwiło to opracowanie „postrzępionych” tablic, zamiast zwykłych stałych prostokątnych (lub o wyższym wymiarze) tablic. Tak więc w dwóch wymiarach poszarpana tablica miałaby wiersze o różnych rozmiarach. Na przykład, biorąc pod uwagę dużą tablicę A (100,100) z wartościami w większości zerowymi, rzadka reprezentacja tablicy, która została zadeklarowana jako SA(100,0) może mieć zmieniony rozmiar każdego wiersza, aby zawierał dokładnie wystarczającą liczbę elementów, aby przechowywać tylko wartości niezerowe A wzdłuż tego rzędu.

Ponieważ tablice większe niż 1024 słowa były segmentowane, ale mniejsze tablice nie, w systemie, w którym brakowało rzeczywistej pamięci, zwiększenie zadeklarowanego rozmiaru zbioru tablic w notatniku z 1000 do powiedzmy 1050 może oznaczać, że program będzie działał z dużo mniejszą ilością " thrashing”, ponieważ tylko mniejsze pojedyncze segmenty w użyciu były potrzebne w pamięci. Rzeczywista pamięć dla segmentu tablicy zostanie przydzielona w czasie wykonywania tylko wtedy, gdy uzyskano dostęp do elementu w tym segmencie, a wszystkie elementy utworzonego segmentu zostaną zainicjowane na zero. Nie inicjalizowanie tablicy na zero na początku było więc zachęcane przez to, zwykle nierozsądne pominięcie.

Zalety struktury stosu

Jedną z fajnych rzeczy w strukturze stosu jest to, że jeśli program się nie powiedzie, wykonywany jest zrzut stosu i bardzo łatwo jest programiście dowiedzieć się, jaki był dokładnie stan uruchomionego programu. Porównaj to do zrzutów pamięci i wymiany pakietów innych systemów.

Inną rzeczą dotyczącą struktury stosu jest to, że programy są domyślnie rekurencyjne. FORTRAN nie miał wspierać rekurencji i być może jedną z przeszkod w zrozumieniu przez ludzi sposobu implementacji ALGOL był sposób implementacji rekurencji. W B5000 to nie był problem – w rzeczywistości mieli odwrotny problem, jak powstrzymać programy przed rekurencyjnością. W końcu nie zawracali sobie głowy. Kompilator Burroughs FORTRAN umożliwiał wywołania rekurencyjne (tak jak każdy inny kompilator FORTRAN), ale w przeciwieństwie do wielu innych komputerów, w systemie opartym na stosie również udały się zwroty z takich wywołań. Mogło to mieć dziwne skutki, jak w przypadku systemu formalnej manipulacji wyrażeniami matematycznymi, którego centralne podprogramy wielokrotnie wywoływały się nawzajem, nigdy nie wracając: duże zadania były kończone przez przepełnienie stosu!

W ten sposób Burroughs FORTRAN miał lepsze sprawdzanie błędów niż inne współczesne implementacje FORTRAN. Na przykład w przypadku podprogramów i funkcji sprawdzano, czy zostały wywołane z odpowiednią liczbą parametrów, co jest normalne w przypadku kompilatorów typu ALGOL. Na innych komputerach takie niezgodności były częstymi przyczynami awarii. Podobnie jest ze sprawdzaniem związanym z tablicą: programy, które były używane przez lata na innych systemach, żenująco często kończyły się niepowodzeniem, gdy były uruchamiane na systemie Burroughsa. W rzeczywistości Burroughs stał się znany z doskonałych kompilatorów i implementacji języków, w tym zorientowanej obiektowo Simula (nadzbiór ALGOL), a Iverson , projektant APL, oświadczył, że implementacja APL w Burroughs była najlepsza, jaką widział. John McCarthy , projektant języka LISP, nie zgodził się z tym, ponieważ LISP był oparty na modyfikowalnym kodzie, nie podobał mu się niemodyfikowalny kod B5000, ale większość implementacji LISP i tak działałaby w środowisku interpretacyjnym.

Pamięć wymagana dla wielu procesów pochodziła w razie potrzeby z puli pamięci systemu. Nie było potrzeby wykonywania SYSGEN w systemach Burroughs, tak jak w konkurencyjnych systemach, w celu wstępnego skonfigurowania partycji pamięci do uruchamiania zadań.

Otagowana architektura

Najbardziej definiującym aspektem B5000 jest to, że jest to maszyna do układania stosów, jak omówiono powyżej. Jednak dwie inne bardzo ważne cechy architektury polegają na tym, że jest ona oparta na znacznikach i deskryptorach.

W oryginalnym B5000 bit flagi w każdym słowie kontrolnym lub słowie numerycznym był odłożony na bok, aby zidentyfikować słowo jako słowo kontrolne lub słowo numeryczne. Był to częściowo mechanizm bezpieczeństwa, który uniemożliwiał programom uszkadzanie słów kontrolnych na stosie.

Później, kiedy B6500 został zaprojektowany, zdano sobie sprawę, że 1-bitowe rozróżnienie słowa sterującego/numerycznego było potężnym pomysłem i zostało rozszerzone do trzech bitów poza 48-bitowym słowem w znaczniku. Bity danych to bity 0–47, a znacznik w bitach 48–50. Bit 48 był bitem tylko do odczytu, a zatem znaczniki nieparzyste wskazywały słowa kontrolne, które nie mogły być zapisane przez program na poziomie użytkownika. Słowa kodowe otrzymały tag 3. Oto lista tagów i ich funkcji:

Etykietka Słowo miłe Opis
0 Dane Wszystkie rodzaje danych użytkownika i systemu (dane tekstowe i liczby o pojedynczej precyzji)
2 Podwójnie Dane o podwójnej precyzji
4 SIW Słowo indeksu kroku (używane w pętlach)
6 Niezainicjowane dane
SCW Słowo sterujące oprogramowania (używane do odcięcia stosu)
1 IRW Pośrednie słowo odniesienia
SIRW Wypchane pośrednie słowo odniesienia
3 Kod Słowo kodowe programu
MSCW Zaznacz słowo kontroli stosu
RCW Zwróć słowo kontrolne
TOSCW Początek słowa kontroli stosu
SD Deskryptor segmentu
5 Deskryptor Deskryptory bloków danych
7 PCW Słowo sterujące programu

Wewnętrznie niektóre maszyny miały 60-bitowe słowa, a dodatkowe bity były używane do celów inżynierskich, takich jak pole korekcji błędów kodu Hamminga , ale nigdy nie były one widziane przez programistów.

Obecne wcielenie tych maszyn, Unisys ClearPath, rozszerzyło znaczniki do znacznika czterobitowego. Poziom mikrokodu, który określał znaczniki czterobitowe, był określany jako poziom Gamma.

Słowa ze znacznikami parzystymi to dane użytkownika, które mogą być modyfikowane przez program użytkownika jako stan użytkownika. Słowa nieparzyste są tworzone i używane bezpośrednio przez sprzęt i reprezentują stan wykonania programu. Ponieważ słowa te są tworzone i używane przez określone instrukcje lub sprzęt, dokładny format tych słów może się zmieniać między implementacją sprzętową a programami użytkownika nie musi być ponownie kompilowany, ponieważ ten sam strumień kodu da te same wyniki, nawet jeśli słowo systemowe format mógł ulec zmianie.

Słowa znacznika 1 reprezentują adresy danych na stosie. Normalny IRW po prostu przechowuje parę adresów do danych na bieżącym stosie. SIRW odwołuje się do danych na dowolnym stosie, umieszczając w adresie numer stosu.

Słowa Tag 5 są deskryptorami, które są dokładniej opisane w następnej sekcji. Słowa znacznika 5 reprezentują adresy danych poza stosem.

Znacznik 7 jest słowem sterującym programu, które opisuje punkt wejścia do procedury. Gdy operatorzy uderzą w PCW, procedura jest wprowadzana. Operator ENTR jawnie wprowadza procedurę (procedura bez zwracania wartości). Funkcje (procedury zwracające wartość) są niejawnie wprowadzane przez operatory, takie jak wywołanie wartości (VALC). Procedury globalne są przechowywane w środowisku D[2] jako SIRW, które wskazują na PCW przechowywane w słowniku segmentów kodu w środowisku D[1]. Środowisko D[1] nie jest przechowywane na bieżącym stosie, ponieważ może się do niego odwoływać wszystkie procesy współdzielące ten kod. W ten sposób kod jest wtórny i współdzielony.

Tag 3 reprezentuje same słowa kodowe, które nie pojawią się na stosie. Znacznik 3 jest również używany dla słów kontrolnych stosu MSCW, RCW, TOSCW.

Rycina 9.2 Z monografii ACM w odnośnikach. Elliot Organick 1973.

Architektura oparta na deskryptorach

Rysunek po lewej pokazuje, w jaki sposób architektura Burroughs Large System była zasadniczo architekturą sprzętową dla programowania obiektowego , czymś, co wciąż nie istnieje w konwencjonalnych architekturach.

Zestawy instrukcji

Istnieją trzy różne zestawy instrukcji dla dużych systemów Burroughs. Wszystkie trzy opierają się na krótkich sylabach, które równomiernie pasują do słów.

B5000, B5500 i B5700

Programy na B5000, B5500 i B5700 składają się z 12-bitowych sylab , cztery do słowa. Architektura ma dwa tryby, Word Mode i Character Mode, a każdy ma osobny repertuar sylab. Procesor może być w stanie sterowania lub w stanie normalnym, a niektóre sylaby są dozwolone tylko w stanie sterowania. Architektura nie przewiduje adresowania rejestrów lub pamięci bezpośrednio; wszystkie odniesienia przechodzą przez 1024-słowną tablicę referencyjną programu, bieżący segment kodu, zaznaczone lokalizacje w stosie lub do rejestrów A i B zawierających dwie górne lokalizacje na stosie. Burroughs numeruje bity w sylabie od 0 (bit wysoki) do 11 (bit niski)

B6500, B7500 i następcy

Programy składają się z 8-bitowych sylab , które mogą być wywołaniem nazwy, wywołaniem wartości lub operatorem, które mogą mieć długość od jednej do dwunastu sylab. Istnieje mniej niż 200 operatorów , z których wszystkie mieszczą się w 8-bitowych sylabach. Wiele z tych operatorów jest polimorficznych, w zależności od rodzaju danych, na których działa dany znacznik. Jeśli zignorujemy potężne operatory skanowania, przesyłania i edycji ciągów, podstawowy zestaw to tylko około 120 operatorów. Jeśli usuniemy operatory zarezerwowane dla systemu operacyjnego, takie jak MVST i HALT, zestaw operatorów powszechnie używanych przez programy na poziomie użytkownika jest mniejszy niż 100. Sylaby Name Call i Value Call zawierają pary adresów ; sylaby Operator albo nie używają adresów, albo używają słów kontrolnych i deskryptorów na stosie.

Wiele procesorów

Linia B5000 była również pionierami w łączeniu wielu procesorów za pomocą szybkiej magistrali. Linia B7000 mogła mieć do ośmiu procesorów, pod warunkiem, że przynajmniej jeden był modułem I/O. RDLK to bardzo niskopoziomowy sposób synchronizacji między procesorami. Wysokim poziomem używanym przez programy użytkownika jest typ danych ZDARZENIE. Typ danych EVENT powodował pewne obciążenie systemu. Aby uniknąć tego obciążenia, można zastosować specjalną technikę blokowania o nazwie zamki Dahm (nazwane na cześć guru oprogramowania Burroughs, Dave'a Dahma).

Znani operatorzy to:

HEYU — wyślij przerwanie do innego procesora
RDLK — Operator semafora niskiego poziomu: Załaduj do rejestru A lokalizację w pamięci podaną przez rejestr A i umieść wartość w rejestrze B w tej lokalizacji pamięci w jednym nieprzerywalnym cyklu. Kompilator Algola wyprodukował kod wywołujący ten operator za pomocą specjalnej funkcji, która umożliwiała operację „swap” na danych jednowyrazowych bez wyraźnej wartości tymczasowej. x:=RDLK(x,y);
WHOI — Identyfikacja procesora
IDLE — Bezczynność do momentu otrzymania przerwania

Dwa procesory rzadko mogą jednocześnie wysyłać sobie nawzajem polecenie „HEYU”, co prowadziło do blokady znanej jako „ śmiertelne uścisk ”.

Wpływ B5000

Bezpośredni wpływ B5000 można zaobserwować w obecnej gamie komputerów mainframe Unisys ClearPath, które są bezpośrednimi potomkami B5000 i nadal posiadają system operacyjny MCP po 40 latach ciągłego rozwoju. Ta architektura jest teraz nazywana emode (dla trybu emulacji), ponieważ architektura B5000 została zaimplementowana na maszynach zbudowanych z procesorów Intel Xeon z zestawem instrukcji x86 jako natywnym zestawem instrukcji, z kodem działającym na tych procesorach emulującym zestaw instrukcji B5000. W tych maszynach miał też być nmode ( tryb natywny ), ale ten został porzucony, więc często można usłyszeć, że maszyny będące następcami B5000 są określane jako "maszyny emode".

Maszyny B5000 zostały zaprogramowane wyłącznie w językach wysokiego poziomu; nie ma asemblera.

Architektura stosu B5000 zainspirowała Chucka Moore'a , projektanta języka programowania Forth , który zetknął się z B5500 podczas pracy w MIT. W Forth - The Early Years Moore opisał wpływ, zauważając, że DUP, DROP i SWAP Fortha pochodzą z odpowiednich instrukcji B5500 (DUPL, DLET, EXCH).

Maszyny B5000 ze swoją architekturą opartą na stosie i pamięcią tagowaną również w dużym stopniu wpłynęły na sowiecką serię komputerów mainframe i superkomputerów Elbrus . Pierwsze dwie generacje serii zawierały pamięć tagowaną i procesory oparte na stosie, które zostały zaprogramowane tylko w językach wysokiego poziomu. Istniał dla nich rodzaj języka asemblerowego , zwany El-76, ale był to mniej więcej modyfikacja ALGOL 68 i wspierała programowanie strukturalne i procedury pierwszej klasy. Późniejsze generacje serii przeszły jednak z tej architektury na podobne do EPIC procesory VLIW .

W Hewlett-Packard projektanci HP3000 systemu biznesowego użył B5500 i byli pod wielkim wrażeniem jego sprzętu i oprogramowania; mieli na celu zbudowanie 16-bitowego minikomputera z podobnym oprogramowaniem. Kilka innych działów HP stworzyło podobne minikomputerowe lub mikroprocesorowe maszyny stosowe. Praca Boba Bartona nad odwróconą notacją polską (RPN) również trafiła do kalkulatorów HP, począwszy od 9100A, a zwłaszcza HP-35 i późniejszych kalkulatorów.

Systemy NonStop zaprojektowane przez Tandem Computers pod koniec lat 70. i na początku lat 80. były również 16-bitowymi maszynami ze stosem, na które B5000 miał pośredni wpływ poprzez połączenie HP 3000, ponieważ kilku wczesnych inżynierów Tandem było wcześniej z HP. Około 1990 roku systemy te przeszły na architekturę MIPS RISC, ale nadal wspierały wykonywanie plików binarnych na maszynie stosu poprzez translację kodu wynikowego lub bezpośrednią emulację. Jakiś czas po 2000 roku systemy te przeszły migrację do architektury Itanium i nadal działały na starszych maszynach binarnych stosu.

Bob Barton był również bardzo wpływowy na Alana Kaya . Kay był również pod wrażeniem architektury B5000 opartej na danych ze znacznikami, co wpłynęło na jego myślenie w rozwoju programowania obiektowego i Smalltalk .

Innym aspektem architektury B5000 było to, że była to bezpieczna architektura, która działa bezpośrednio na sprzęcie. Ta technika ma potomków w dzisiejszych maszynach wirtualnych w ich próbach zapewnienia bezpiecznych środowisk. Jednym z godnych uwagi takich produktów jest Java JVM, która zapewnia bezpieczną piaskownicę, w której działają aplikacje.

Wartość powiązania sprzęt-architektura, które istniało przed emode, byłaby w znacznym stopniu zachowana na maszynach opartych na architekturze x86 do tego stopnia, że ​​MCP był jedynym programem sterującym, ale wsparcie zapewniane przez te maszyny jest nadal gorsze od zapewnianego na maszyny, w których zestaw instrukcji B5000 jest zestawem instrukcji natywnych. Mało znany procesor Intel architektura że faktycznie poprzedzone 32-bitowe implementacje zestawu instrukcji x86 The Intel iAPX 432 , by zapewniły równoważną podstawy fizyczne, jak to było w istocie zbyt architektura zorientowana obiektowo.

Zobacz też

Uwagi

Bibliografia

  • The Extended ALGOL Primer (trzy tomy), Donald J. Gregory.
  • Architektura komputerowa: podejście strukturalne, R. Doran, Academic Press (1979).
  • Stack Computers: The New Wave, Philip J. Koopman, dostępne pod adresem: [1]
  • Instrukcje B5500, B6500, B6700, B6800, B6900, B7700 na stronie: bitsavers.org

Dalsza lektura

Zewnętrzne linki