Biorąc pod uwagę konkretny system komputerowy, czy jest możliwe oszacowanie faktycznego dokładnego czasu działania fragmentu kodu zespołu


23

to jest fragment kodu asemblera

section .text
    global _start       ;must be declared for using gcc
_start:                     ;tell linker entry point
    mov edx, len    ;message length
    mov ecx, msg    ;message to write
    mov ebx, 1      ;file descriptor (stdout)
    mov eax, 4      ;system call number (sys_write)
    int 0x80        ;call kernel
    mov eax, 1      ;system call number (sys_exit)
    int 0x80        ;call kernel

section .data

msg db  'Hello, world!',0xa ;our dear string
len equ $ - msg         ;length of our dear string

Biorąc pod uwagę konkretny system komputerowy, czy można dokładnie przewidzieć rzeczywisty czas działania fragmentu kodu asemblera.


30
Czy „uruchom kod na tym komputerze i użyj stopera” jest prawidłową odpowiedzią?
Draconis

4
Podejrzewam, że większość czasu poświęconego na wykonanie tego fragmentu kodu czeka na operacje wejścia / wyjścia. Czas potrzebny na wykonanie poszczególnych instrukcji jest w pewnym stopniu przewidywalny, jeśli znasz lokalizację kodu w pamięci i wszystkie szczegóły dotyczące procesora (które są obecnie bardzo skomplikowane), ale na szybkość wpływa również pamięć i dysk, więc „ Muszę też znać bardzo dużą liczbę szczegółów na ich temat. Więc jeśli nie weźmie się pod uwagę zjawisk fizycznych (które również wpływają na czas), można powiedzieć, że jest to przewidywalne, ale niewyobrażalnie trudne.
IllidanS4 chce, aby Monica wróciła

4
zawsze można oszacować ...
sudo rm -rf slash

3
Czy nie jest to również niemożliwe z powodu problemu zatrzymania? Możemy udowodnić, że jakiś kod się zatrzyma, ale nie możemy mieć algorytmu, który określa to dla wszystkich możliwych kodów.
kutschkem

2
@Falco To byłaby właściwość danego systemu. Niektóre wolnostojące implementacje C nie mają systemu operacyjnego; wszystko, co działa, to główna pętla (a nawet pętla ;-)), która może, ale nie musi, odczytywać adresy sprzętowe do wprowadzania.
Peter - Przywróć Monikę

Odpowiedzi:


47

Mogę jedynie zacytować z podręcznika dość prymitywnego procesora, procesora 68020 z około 1986 roku: „Obliczenie dokładnego czasu wykonywania sekwencji instrukcji jest trudne, nawet jeśli masz dokładną wiedzę na temat implementacji procesora”. Których nie mamy. W porównaniu z nowoczesnym procesorem ten procesor był prymitywny .

Nie mogę przewidzieć czasu działania tego kodu i ty też nie. Ale nie można nawet zdefiniować, co to jest „środowisko wykonawcze” fragmentu kodu, gdy procesor ma ogromne pamięci podręczne i potężne funkcje poza kolejnością. Typowy nowoczesny procesor może mieć 200 instrukcji „w locie”, czyli na różnych etapach wykonania. Czas od próby odczytania pierwszego bajtu instrukcji do wycofania ostatniej instrukcji może być dość długi. Ale faktyczne opóźnienie wszystkich innych zadań, które procesor musi wykonać, może być (i zwykle jest) znacznie mniejsze.

Oczywiście wykonanie dwóch połączeń z systemem operacyjnym czyni to całkowicie nieprzewidywalnym. Nie wiesz, co właściwie robi „pisanie na standardowe wyjście”, więc nie możesz przewidzieć czasu.

I nie możesz znać szybkości zegara komputera w momencie uruchomienia kodu. Może być w pewnym trybie oszczędzania energii, komputer może mieć zmniejszoną prędkość zegara, ponieważ się rozgrzał, więc nawet ta sama liczba cykli zegara może zająć różną ilość czasu.

Podsumowując: Całkowicie nieprzewidywalny.


12
Myślę, że twoje wnioski są zbyt mocne. Opóźnienia i przepustowość są powszechnymi miernikami służącymi do pomiaru „czasu działania” programu. Możesz także po prostu wybrać odpowiednią definicję „środowiska wykonawczego”. Ponadto, jeśli masz pełną migawkę stanu systemu, hw i sw oraz doskonałą znajomość wewnętrznych elementów procesora, możesz przewidzieć czas działania. W firmie Intel prawdopodobnie potrafią oszacować czas działania, nawet tutaj na SO możemy przewidywać opóźnienia i tput z dokładnością cyklu. W tym przypadku, oprócz syscalls, nie jest to nawet takie trudne.
Margaret Bloom

10
@MargaretBloom nawet wtedy. Kładę telefon zbyt blisko piekarnika, podkręca procesor, aby zarządzać temperaturą, a twoje oszacowanie czasu pracy jest nagle zbyt niskie. I nawet jeśli liczysz w cyklach i nie wykonujesz wywołań systemowych, inne wątki i procesory mogą ładnie grać z zawartością pamięci RAM lub mogą zrzucić twoją pamięć na dysk twardy podczas wymiany, na podstawie nieprzewidzianych okoliczności, od mocy gwałtownie spowalnia dysk twardy na tyle, że konkurencyjny wątek dostaje wystarczająco dużo pamięci, aby zniszczyć twój, aż do wątków prosto w kostkę, aby zobaczyć, ile czasu marnować.
John Dvorak

6
Poza tym „pełna znajomość stanu systemu, hw i sw” jest dość wysokim porządkiem, jak uważa. Dodaj „10 ms wcześniej”, a już pytasz o niemożliwe. A jeśli implementacja sprzętowego generowania liczb losowych w twoim CPU wykorzystuje zjawiska kwantowe (prawdopodobnie tak jest), a niektóre wątki na CPU tak go nazywają, to nawet nie wiedząc, że pełny stan wszechświata 3000 km wokół komputera cię uratuje. A w MWI nie można nawet zgadnąć, co należy.
John Dvorak

8
@Nat: Nawet w kryptografii „stały czas” tak naprawdę nie oznacza absolutnie stałego - oznacza po prostu, że czas działania nie ma systematycznych zmian zależnych od tajnych danych i może być z nim skorelowany statystycznie. W praktyce często zakłada się, że jeśli wybrana ścieżka kodu i wzorzec wykonywanych operacji dostępu do pamięci nie zależą od tajnych danych, i jeśli unikane są określone instrukcje zajmujące różną ilość czasu (lub ich dane wejściowe są maskowane mam nadzieję, że wyeliminuje korelację), prawdopodobnie jest wystarczająco dobra. Poza tym naprawdę musisz to zmierzyć.
Ilmari Karonen

2
68020 to złożona bestia ... spróbuj
MCS51

30

Nie możesz tego ogólnie robić, ale pod pewnymi względami bardzo możesz, i było kilka historycznych przypadków, w których naprawdę musiałeś .

Atari 2600 (lub Atari wideo Computer System) był jednym z pierwszych systemów do gier wideo do domu i został po raz pierwszy wydany w 1978 roku W przeciwieństwie do późniejszych systemach ery Atari nie może sobie pozwolić, aby dać urządzeniem z bufora ramki, co oznacza, że procesor miał aby uruchomić kod na każdej linii skanowania, aby określić, co ma zostać wyprodukowane - jeśli ten kod zabrałby 17.08 mikrosekund do uruchomienia (interwał HBlank), grafika nie byłaby odpowiednio ustawiona, zanim linia skanowania zacznie je rysować. Co gorsza, jeśli programista chciał narysować bardziej złożoną zawartość niż normalnie zezwalały Atari, musiał mierzyć dokładne czasy instrukcji i zmieniać rejestry graficzne podczas rysowania wiązki, z rozpiętością 57,29 mikrosekund dla całej linii skanowania.

Jednak Atari 2600, podobnie jak wiele innych systemów opartych na 6502, miał bardzo ważną funkcję, która umożliwiła staranne zarządzanie czasem wymagane w tym scenariuszu: procesor, pamięć RAM i sygnał telewizyjny działały w oparciu o zegary oparte na tym samym urządzeniu głównym zegar. Sygnał telewizyjny pobiegł z zegarem 3,98 MHz, dzieląc powyższe czasy na całkowitą liczbę „kolorowych zegarów”, które zarządzały sygnałem telewizyjnym, a cykl procesora i zegarów pamięci RAM wynosił dokładnie trzy kolorowe zegary, co pozwala na ustawienie zegara procesora dokładna miara czasu w stosunku do bieżącego sygnału telewizyjnego postępu. (Aby uzyskać więcej informacji na ten temat, zapoznaj się z Przewodnikiem programisty Stella , napisanym dla emulatora Stella Atari 2600 ).

Ponadto to środowisko operacyjne oznaczało, że każda instrukcja CPU miała określoną liczbę cykli, którą zajmie w każdym przypadku, a wielu programistów 6502 opublikowało te informacje w tabelach referencyjnych. Rozważmy na przykład ten wpis instrukcji CMP(Porównaj pamięć z akumulatorem) zaczerpnięty z tej tabeli :

CMP  Compare Memory with Accumulator

     A - M                            N Z C I D V
                                    + + + - - -

     addressing    assembler    opc  bytes  cycles
     --------------------------------------------
     immediate     CMP #oper     C9    2     2
     zeropage      CMP oper      C5    2     3
     zeropage,X    CMP oper,X    D5    2     4
     absolute      CMP oper      CD    3     4
     absolute,X    CMP oper,X    DD    3     4*
     absolute,Y    CMP oper,Y    D9    3     4*
     (indirect,X)  CMP (oper,X)  C1    2     6
     (indirect),Y  CMP (oper),Y  D1    2     5*

*  add 1 to cycles if page boundary is crossed

Wykorzystując wszystkie te informacje, Atari 2600 (i inni programiści 6502) byli w stanie dokładnie określić, ile czasu zajmuje ich wykonanie kodu, i zbudować procedury, które zrobiły to, czego potrzebowały i nadal spełniały wymagania dotyczące czasu sygnału telewizyjnego Atari. A ponieważ czas był tak dokładny (szczególnie w przypadku marnujących czas instrukcji, takich jak NOP), byli w stanie nawet użyć go do modyfikacji grafiki podczas rysowania.


Oczywiście 6502 Atari jest bardzo specyficznym przypadkiem, a wszystko to jest możliwe tylko dlatego, że system miał wszystkie następujące elementy:

  • Główny zegar, który uruchamiał wszystko, w tym pamięć RAM. Nowoczesne systemy mają niezależne zegary dla procesora i pamięci RAM, przy czym zegar RAM jest często wolniejszy, a dwa niekoniecznie są zsynchronizowane.
  • Żadnego buforowania - 6502 zawsze uzyskuje bezpośredni dostęp do pamięci DRAM. Nowoczesne systemy mają pamięci podręczne SRAM, które utrudniają przewidywanie stanu - chociaż być może nadal można przewidzieć zachowanie systemu z pamięcią podręczną, jest to zdecydowanie trudniejsze.
  • Żadne inne programy nie działają jednocześnie - program na kartridżu miał pełną kontrolę nad systemem. Nowoczesne systemy uruchamiają wiele programów jednocześnie, używając niedeterministycznych algorytmów szeregowania.
  • Prędkość zegara na tyle wolna, że ​​sygnały mogą przemieszczać się w systemie w czasie. W nowoczesnym systemie z zegarem 4 GHz (na przykład) potrzeba fotonu światła 6,67 cykli zegara, aby przejść przez półmetrową płytę główną - nigdy nie można oczekiwać, że nowoczesny procesor wejdzie w interakcję z czymś innym na płycie w jednym cyklu, ponieważ sygnał na płycie potrzebuje więcej niż jednego cyklu, aby dotrzeć nawet do urządzenia.
  • Dobrze zdefiniowana prędkość zegara, która rzadko się zmienia (1,19 MHz w przypadku Atari) - prędkości procesorów nowoczesnych systemów zmieniają się cały czas, podczas gdy Atari nie mógł tego zrobić bez wpływu na sygnał telewizyjny.
  • Opublikowane czasy cyklu - x86 nie określa, jak długo trwa jakakolwiek jego instrukcja.

Wszystkie te rzeczy połączyły się, aby stworzyć system, w którym można było stworzyć zestawy instrukcji, które zajęły dokładnie tyle czasu - i do tego zastosowania dokładnie tego wymagano. Większość systemów nie ma tego stopnia precyzji po prostu dlatego, że nie jest to konieczne - obliczenia albo są wykonywane, gdy są one wykonane, albo jeśli potrzebna jest dokładna ilość czasu, można zapytać o niezależny zegar. Ale jeśli potrzeba jest odpowiednia (na przykład w niektórych systemach wbudowanych), może się nadal pojawiać, a Ty będziesz w stanie dokładnie określić, ile czasu zajmuje uruchomienie kodu w tych środowiskach.


Powinienem również dodać duże, masowe zastrzeżenie, że wszystko to dotyczy tylko konstruowania zestawu instrukcji asemblacyjnych, które zajmą dokładnie tyle czasu. Jeśli chcesz zrobić dowolny zestaw, nawet w tych środowiskach, i zapytać: „Jak długo trwa to wykonanie?”, Kategorycznie nie możesz tego zrobić - to jest problem zatrzymania , który okazał się nierozwiązywalny.


EDYCJA 1: W poprzedniej wersji tej odpowiedzi stwierdziłem, że Atari 2600 nie ma możliwości poinformowania procesora o tym, gdzie jest w sygnale telewizyjnym, co zmusiło go do utrzymania liczenia i synchronizacji całego programu od samego początku. Jak wskazano mi w komentarzach, dotyczy to niektórych systemów, takich jak ZX Spectrum, ale nie jest tak w przypadku Atari 2600, ponieważ zawiera rejestr sprzętowy, który zatrzymuje procesor do momentu wystąpienia następnego interwału wygaszania poziomego, a także funkcja pozwalająca na rozpoczęcie pionowego interwału wygaszania do woli. W związku z tym problem zliczania cykli jest ograniczony do każdej linii skanowania i staje się dokładny tylko wtedy, gdy programista chce zmienić zawartość podczas rysowania linii skanowania.


4
Należy również zauważyć, że większość gier nie działała idealnie - na wyjściu wideo można było zobaczyć wiele artefaktów z powodu niedopasowanego taktowania sygnału wideo, albo z powodu błędu programatora (nieprawidłowe oszacowanie taktowania procesora) lub po prostu za dużo praca do zrobienia. Był również bardzo delikatny - jeśli trzeba było naprawić błąd lub dodać nowe funkcje, najprawdopodobniej zepsułbyś czas, czasem nieuchronnie. Było fajnie, ale także koszmar :) Nie jestem nawet pewien, czy szybkość zegara zawsze była dokładnie poprawna - np. Przy przegrzaniu, zakłóceniach itp. Ale to zdecydowanie pokazuje, że nawet wtedy było ciężko.
Luaan

1
Dobra odpowiedź, chociaż chciałbym się przekonać, że nie musisz liczyć liczby cykli dla każdej instrukcji w Atari 2600. Ma dwie funkcje, które pomogą ci tego nie robić: licznik czasu, który inicjujesz i następnie odpytaj, aby sprawdzić, czy osiągnął 0, i rejestr, który zatrzymuje procesor do momentu rozpoczęcia następnego poziomego wygaszania. Wiele innych urządzeń, takich jak ZX Spectrum, nie ma czegoś takiego, i faktycznie musisz liczyć każdy pojedynczy cykl spędzony po przerwaniu wygaszania pionowego, aby wiedzieć, gdzie jesteś na ekranie.
Martin Vilcans

1
Twierdziłbym, że problem Haltinga nie dotyczy ściśle Atari. Jeśli wykluczysz możliwości wejścia / wyjścia Atari i ograniczysz je do typowej pamięci ROM kartridży, wówczas ilość pamięci jest ograniczona. W tym momencie masz skończoną maszynę stanu, więc każdy program na niej musi albo zatrzymać się, albo wejść w stan, który wprowadził wcześniej, prowadząc do udowodnionej nieskończonej pętli w skończonym czasie.
user1937198

2
@ user1937198 128 bajtów stanu (plus wszystko, co jest w rejestrach) to WIĘCEJ, to wystarczająca przestrzeń stanu, aby różnica między tą a teoretyczną nieskończoną taśmą maszyny Turinga była rozróżnieniem, które ma znaczenie tylko w teorii. Do diabła, nie możemy praktycznie przeszukać 128 bitów czegoś takiego jak klucz AES .... Przestrzeń stanu rośnie strasznie szybko, gdy dodajesz bity. Nie zapominaj, że odpowiednik „Wyłącz przerwania; zatrzymanie byłoby prawie na pewno możliwe.
Dan Mills

1
„to jest problem zatrzymania, który okazał się nierozwiązywalny. Jeśli na to wpadniesz, musisz rozbić stoper i uruchomić kod”. - to nie ma sensu. Nie można uniknąć dowodu Turinga poprzez „faktyczne” uruchomienie kodu zamiast jego symulacji. Jeśli się zatrzyma, możesz określić, ile czasu potrzeba, aby się zatrzymać. Jeśli się nie zatrzyma, nigdy nie będziesz mieć pewności (ogólnie), czy zatrzyma się w przyszłości, czy będzie działać wiecznie. To ten sam problem z prawdziwym lub symulowanym stoperem. Przynajmniej w symulacji łatwiej można sprawdzić stan wewnętrzny pod kątem oznak zapętlenia.
benrg

15

Grają tutaj dwa aspekty

Jak wskazuje @ gnasher729, jeśli znamy dokładne instrukcje do wykonania, nadal trudno jest oszacować dokładny czas działania z powodu takich rzeczy, jak buforowanie, przewidywanie gałęzi, skalowanie itp.

Sytuacja jest jednak jeszcze gorsza. Biorąc pod uwagę część zestawu, nie można wiedzieć, które instrukcje zostaną uruchomione, ani nawet wiedzieć, ile instrukcji będzie działać. Wynika to z twierdzenia Rice'a: gdybyśmy mogli to dokładnie ustalić, moglibyśmy wykorzystać te informacje do rozwiązania problemu zatrzymania, co jest niemożliwe.

Kod asemblera może zawierać skoki i rozgałęzienia, które wystarczą, aby pełny ślad programu był nieskończony. Pracowano nad konserwatywnymi przybliżeniami czasu wykonania, które dają górne granice wykonania, poprzez takie rzeczy jak semantyka kosztów lub systemy typów z adnotacjami. Nie znam się na konkretnym montażu, ale nie zdziwiłbym się, gdyby coś takiego istniało.


4
Chodzi mi o to, że problem zatrzymania dotyczy bezpośrednio tutaj, ponieważ gdybyśmy znali czas działania, wiedzielibyśmy, czy się zatrzyma. Również fakt, że nie ma warunkowych warunków, nawet tutaj nie pomaga, ponieważ w x86 movjest Turing-Complete
BlueRaja - Danny Pflughoeft

7
Rice i problem zatrzymania są stwierdzeniami o dowolnych (dowolnych) programach - ale OP tutaj określił jeden konkretny fragment kodu w pytaniu. Możesz określić właściwości semantyczne i zatrzymujące dotyczące poszczególnych lub ograniczonych kategorii programów, prawda? Po prostu nie ma ogólnej procedury obejmującej wszystkie programy.
Daniel R. Collins

2
Możemy definitywnie wiedzieć, która instrukcja zostanie uruchomiona w następnej kolejności, nie możemy powiedzieć, czy kiedykolwiek uderzymy w sys_exita tym samym zatrzymamy stoper. Jeśli ograniczymy się do zamykania programów, co jest uzasadnione w przypadku takiego praktycznego pytania, wówczas odpowiedź jest w rzeczywistości tak (pod warunkiem, że masz doskonałą migawkę stanu, hw i sw, systemu tuż przed uruchomieniem programu).
Margaret Bloom

1
@ BlueRaja-DannyPflughoeft Mov jest w pełni ukończony, ale nie ma go tutaj w kodzie OP. Ale to zresztą poza tym - ints mogą wykonywać dowolny kod, czekać na dowolne operacje we / wy itp.
Luaan

2

Czy wybór „systemu komputerowego” obejmowałby mikrokontrolery? Niektóre mikrokontrolery mają bardzo przewidywalne czasy wykonania, na przykład 8-bitowa seria PIC ma cztery cykle zegarowe na instrukcję, chyba że instrukcja rozgałęzia się na inny adres, czyta z pamięci flash lub jest specjalną instrukcją składającą się z dwóch słów.

Przerwania będą oczywiście zakłócać tego rodzaju timimg, ale można wiele zrobić bez obsługi programu obsługi przerwań w konfiguracji „bez metalu”.

Używając asemblera i specjalnego stylu kodowania, można napisać kod, którego wykonanie zawsze zajmie tyle samo czasu. Teraz nie jest tak powszechne, że większość wariantów PIC ma wiele timerów, ale jest to możliwe.


2

W erze komputerów 8-bitowych niektóre gry zrobiły coś takiego. Programiści wykorzystali dokładny czas potrzebny na wykonanie instrukcji, w oparciu o czas, jaki zajęli i znaną częstotliwość taktowania procesora, aby zsynchronizować się z dokładnymi czasami sprzętu wideo i audio. W tamtych czasach wyświetlacz był monitorem z lampą elektronopromieniową, który cyklicznie przesuwał się po każdej linii ekranu ze stałą szybkością i malował ten rząd pikseli poprzez włączanie i wyłączanie promienia katodowego w celu aktywacji lub dezaktywacji luminoforów. Ponieważ programiści musieli powiedzieć sprzętowi wideo, co wyświetlać tuż przed dotarciem wiązki do tej części ekranu, i dopasować resztę kodu do pozostałego czasu, dlatego nazwali to „ściganiem wiązki”.

Absolutnie nie działałoby na żadnym nowoczesnym komputerze ani w kodzie takim jak twój przykład.

Dlaczego nie? Oto kilka rzeczy, które zepsułyby prosty, przewidywalny czas:

Szybkość procesora i pobieranie pamięci są wąskimi gardłami w czasie wykonywania. Stratą pieniędzy jest szybsze uruchamianie procesora niż jest w stanie pobrać instrukcje do wykonania lub zainstalować pamięć, która może dostarczyć bajty szybciej, niż procesor może je zaakceptować. Z tego powodu stare komputery działały na tym samym zegarze. Nowoczesne procesory działają znacznie szybciej niż pamięć główna. Zarządzają tym dzięki pamięci podręcznej instrukcji i danych. Procesor nadal się zatrzymuje, jeśli kiedykolwiek będzie musiał czekać na bajty, które nie znajdują się w pamięci podręcznej. Te same instrukcje będą zatem działać znacznie szybciej, jeśli są już w pamięci podręcznej, niż jeśli ich nie ma.

Ponadto nowoczesne procesory mają długie potoki. Utrzymują wysoką przepustowość, zlecając kolejną część układu wstępnym pracom nad kolejnymi kilkoma instrukcjami w przygotowaniu. To się nie powiedzie, jeśli CPU nie wie, jaka będzie następna instrukcja, co może się zdarzyć, jeśli istnieje gałąź. Dlatego procesory próbują przewidzieć skoki warunkowe. (Nie masz żadnego w tym fragmencie kodu, ale być może był to nieprzewidziany warunkowy skok, który zablokował potok. Poza tym dobra wymówka, aby połączyć tę legendarną odpowiedź.) Podobnie, systemy, które wzywają int 80pułapkę do trybu jądra używają skomplikowanej funkcji procesora, bramki przerwań, która wprowadza nieprzewidziane opóźnienie.

Jeśli system operacyjny korzysta z zapobiegawczej wielozadaniowości, wątek uruchamiający ten kod może w dowolnym momencie utracić swój przedział czasu.

Ściganie wiązki działało również tylko dlatego, że program działał na goły metal i uderzył bezpośrednio w sprzęt. Tutaj dzwonisz, int 80aby wykonać połączenie systemowe. To przekazuje kontrolę systemowi operacyjnemu, co nie daje żadnej gwarancji czasu. Następnie powiesz mu, że wykonuje operacje we / wy w dowolnym strumieniu, który mógł zostać przekierowany na dowolne urządzenie. To zbyt abstrakcyjne, żebyś mógł powiedzieć, ile czasu zajmuje We / Wy, ale z pewnością zdominuje czas spędzony na wykonywaniu instrukcji.

Jeśli chcesz dokładnego pomiaru czasu w nowoczesnym systemie, musisz wprowadzić pętlę opóźnienia. Musisz sprawić, by szybsze iteracje przebiegały z prędkością najwolniejszą, a odwrotność nie jest możliwa. Jednym z powodów, dla których ludzie to robią w prawdziwym świecie, jest zapobieganie wyciekaniu informacji kryptograficznych do osoby atakującej, która może czas, którego żądania zajmują dłużej niż inne.


1

Jest to nieco styczne, ale wahadłowiec kosmiczny miał 4 nadmiarowe komputery, które polegały na dokładnej synchronizacji, tzn. Dokładnie dopasowanym czasie działania.

Pierwsza próba uruchomienia promu kosmicznego została oczyszczona, gdy komputer Backup Flight Software (BFS) odmówił synchronizacji z czterema komputerami Primary Avionics Software System (PASS). Szczegóły w „The Bug Heard Round the World” tutaj . Fascynująca lektura na temat tego, jak oprogramowanie zostało opracowane, aby dopasować cykl do cyklu i może dać interesujące tło.


0

Myślę, że mieszamy tutaj dwie różne kwestie. (I tak, wiem, że powiedzieli to inni, ale mam nadzieję, że mogę to wyrazić jaśniej).

Najpierw musimy przejść od kodu źródłowego do sekwencji faktycznie wykonanych instrukcji (która wymaga znajomości danych wejściowych, a także kodu - ile razy okrążasz pętlę? Którą gałąź wykonuje się po teście? ). Z powodu problemu zatrzymania sekwencja instrukcji może być nieskończona (nieterminacja) i nie zawsze można to ustalić statycznie, nawet przy znajomości danych wejściowych.

Po ustaleniu sekwencji instrukcji do wykonania, należy następnie określić czas wykonania. Można to z pewnością oszacować przy pewnej wiedzy na temat architektury systemu. Problem polega jednak na tym, że na wielu współczesnych maszynach czas wykonania zależy w dużej mierze od buforowania pobrań pamięci, co oznacza, że ​​zależy zarówno od danych wejściowych, jak i od wykonanych instrukcji. Zależy to również od prawidłowego odgadnięcia warunkowych miejsc docelowych oddziałów, które ponownie zależą od danych. To będzie tylko szacunek, nie będzie dokładny.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.