Последната актуализация на този раздел е от 2020 година.

 

5.4.5  Точно прекъсване. Определения и реализации

 

 

      За изложението по-надолу ще ни е необходимо понятието процес. Изпълнението на текущата програма представлява процес. Процесът трябва да завършва с едни и същи резултати, независимо на какъв процесор той се изпълнява. Състоянието на процеса се определя от съдържанието на следните структурни елементи:

·         Програмен брояч на процесора ;

·         Процесорни регистри (с общо предназначение, системни – на състоянието, на флаговете и др. подобни) ;

·         Оперативна памет.

      В системи с реално време е необходимо да се отчита още влиянието на кеш паметта, на буферите за асоциативно преобразуване на MMU, както и на таблиците за динамично предсказване на условните преходи.

      Всяка изпълнена машинна команда обновява по някакъв начин състоянието на процеса.

·         Основните команди, като например, аритметическите и логическите, обновяват съдържанието на регистрите, както и на програмния брояч ;

·         Командите за преход обновяват програмния брояч и таблиците за динамично предсказване на условните преходи ;

·         Командите за зареждане обновяват съдържанието на регистрите, на програмния брояч и на кеш паметта. При пропуск в кеш паметта, когато се замества кеш линия, се обновява и оперативната памет ;

·         Командите за запис обновяват съдържанието на оперативната памет (или на кеш паметта) и на програмния брояч

      Като за начало ще припомним основата, върху която ще развиваме изложението тук. Прекъсването беше определено като случайно събитие, при което процесорът трябва да преустанови изпълнението на текущия процес, да съхрани неговото състояние и да започне изпълнението на друг процес, с програма за обработване на прекъсвания (Interrupt Handler - IH). След завършване на обслужването на прекъсването, състоянието на прекъснатия процес следва да се възстанови.

      В зависимост от източника на ЗП, прекъсването на изпълнението на текущата машинна команда се определят като:

1.       Вътрешно, когато е причинено от машинна команда в процесора:

·         Програмно прекъсване (Software Interrupt), ако е предизвикано от специална команда ;

·         Изключение (Exception, Fault, Abort), ако е предизвикано от грешка при изпълнение на командата ;

2.       Външно, ако прекъсването е предизвикано от външно за процесора събитие.

      Съхранението и възстановяването на състоянието на процеса може да бъде реализирано апаратно, програмно или смесено. Ще се спрем на смесения вариант:

·           МППОП (вижте раздел 5.4.1) записва съдържанието на програмния брояч в специален регистър (РАВ – регистър на адреса за връщане), след което записва като ново съдържание в програмния брояч фиксиран служебен адрес – начален адрес на програма Interrupt Handler. Така след затваряне на командния цикъл се стартира служебната програма Interrupt Handler ;

·           Всички останали елементи, формиращи състоянието на процесора, се съхраняват от програмата IH в програмния стек ;

·           Последните действия, които изпълнява програмата IH, са свързани с възстановяването на състоянието на процесора с извличане от стека на преди това съхраненото състояние ;

·           Последната команда, която изпълнява програма IH, е командата “Връщане от прекъсване”, която в случая пренася съдържанието на регистър РАВ в програмния брояч.

      Въпреки че по-горе накратко беше изказано някакво мнение, възниква въпрос: къде все пак следва да се съхранява информацията при осъществяване на прекъсването? Ще коментираме няколко възможности.

      Информацията, която следва да се съхрани при прекъсване може да бъде записана в множество вътрешни регистри, които са достъпни за операционната система. Тази стратегия обаче изявява следния проблем: не следва да се изпраща потвърждение към контролера на прекъсванията, докато не бъде прочетен целия обем от важни данни, тъй като следващото прекъсване, при съхранение на състоянието, може да унищожи съдържанието на част от все още непрочетените регистри. Задържането във времето на сигнала за потвърждение води към продължителни престои, по време на които е забранено приемането на други прекъсвания, което пък от своя страна може да доведе до загуба на ЗП и съответно на данни. Именно по тази причина повечето процесори съхраняват информацията в стек.

      Използването на програмния стек също крие своите проблеми. Първият въпрос, който възниква е: кой стек да бъде използван? Ако се избере текущият стек, той най-вероятно ще се окаже стек на потребителски процес. Указателят на стека може да съдържа недопустима стойност, при което опитите за запис могат да бъдат фатални за данните. Освен това той може да сочи края на страницата. Възникването на подобна грешка по време на обработване на апаратно прекъсване води до друг сериозен проблем – къде да се съхрани състоянието, за да се обработи така възникналата грешка, свързана с отсъствието на необходимата страница?

      Ако се използва стека на ядрото на ОС вероятността указателят на стека да съдържа допустима стойност и да указва на фиксирана страница, е по-голяма. Но превключването в режим на ядрото може да наложи изменения в контекста на MMU, и вероятно ще направи недействително съдържанието на кеш паметта и TLB. Тяхното статистическо или динамическо претоварване ще увеличи времето за обработка на прекъсването и ще доведе до излишна загуба на време.

      Към горните проблеми трябва да добавим и тези, които са породени от това, че съвременните процесори са суперскаларни и суперконвейерни.

Точни и неточни прекъсвания. Определения

      След затваряне на командния цикъл прекъснатия преди това процес трябва да продължи изпълнението си, все едно не е бил прекъсван. Тази логика е тривиална, но в повечето съвременни процесори е доста трудно тя да бъде спазена и по някога се налага тя да бъде игнорирана. Прекъсванията, които гарантират изпълнението на споменатата логика, се наричат точни (precise), останалите се наричат неточни (imprecise).

      Формално прекъсването се определя като точно, ако са изпълнени следните условия:

1.       Съдържанието на програмния брояч е успешно съхранено ;

2.       Всички команди, предхождащи тази, на която сочи програмния брояч, са били нормално изпълнени и състоянието на процеса е било коректно съхранено ;

3.       Всички команди, следващи тази, на която сочи програмния брояч, не са били изпълнени и състоянието на процеса не е изменено ;

4.       Прекъснатата команда, в зависимост от вида на прекъсването, е била изцяло изпълнена, или въобще не е била изпълнена.

      Описаната ситуация може да се илюстрира със следната рисунка:

 

Фиг. 5.4.5.1.  Ситуация на точно прекъсване

 

      Всички прекъсвания, които не отговарят на горните 4 условия, могат да се определят като неточни.  Първите две условия не се нуждаят от коментар. Ще се спрем на третото.

·         Командата, която се е изпълнявала в момента на появата на външното прекъсване, следва да обнови състоянието на процеса, преди последното да бъде съхранено. Това се отнася и до командите, водещи до програмно прекъсване. И в двата случая РАВ ще съдържа следващия адрес, от който ще продължи изпълнението след завръщане от прекъсването ;

·         Командата, която предизвиква “изключение”, се определя като лоша команда. Нейните резултати се считат за некоректни, поради което тя не следва да обновява състоянието на процеса. Вместо това в РАВ се записва нейният адрес, след което се извиква програмата IH, която се опитва да поправи грешката. След като програмата IH върне управлението, лошата команда се изпълнява повторно. Ако тя отново генерира същото изключение, се приема, че грешката е непоправима и процесорът генерира фатално прекъсване.

      Очевидно е, че външното прекъсване трябва да бъде винаги точно. Кому е нужен процесор, който не може коректно да възстанови процес след обработка на прекъсване, например от таймера?

      Програмните прекъсвания и изключенията могат да бъдат и точни и неточни. Има случаи, когато без точни изключения е невъзможно, например, ако в процесора има устройство MMU. В този случай когато има неуспешно обръщение към TLB, управлението се предава на съответната програма за обслужване на изключението, която добавя необходимата страница в TLB, след което трябва повторно да изпълни командата, генерирала изключението.

      В микроконтролерите изключенията могат да бъдат неточни. Например, ако команда за запис е генерирала изключение по причина на някаква грешка в паметта, вместо да се прави опит за поправка на грешката и повторно да се изпълни прекъснатата команда, се предпочита ресет и презареждане на микроконтролера и повторно стартиране на програмата, което съответства на действията на алармения таймер, когато програмата му “увисва".

      Аналогично на точното прекъсване, ще илюстрираме неточното.

 

Фиг. 5.4.5.2.  Ситуация на неточно прекъсване

      Виждаме команди, обкръжаващи командата, сочена от програмния брояч, които са в различна степен на изпълнение. В тази ситуация процесорите обикновено поместват цялата информация в стека, за да дадат възможност на ОС да знае в какъв стадий се намира цялото изпълнение. Изхождайки от това положение, за възобновяване на изпълнението е необходим доста сложен програмен код. Всичко това води към значително забавяне на обработката, което от своя страна води до твърде нелепата ситуация, в която бърз суперскаларен процесор се оказва непригоден за работа в системи с реално време.

Точни прекъсвания в процесори с последователно изпълнение на командите

      В такива процесори реализацията на точното прекъсване е сравнително лесно. Тъй като в даден момент се изпълнява една (поредна, текуща) команда, то при настъпване на прекъсване, всички предхождащи тази команда команди са вече изпълнени, а следващите след нея все още не са изпълнени. При тази ситуация, за реализация на точно прекъсване е достатъчно да се установи, че прекъснатата команда никога не извършва обновяване на състоянието на процеса, докато не се стане ясно дали тя е генерирала изключение или не. Мястото, в което процесорът трябва да определи ще позволи ли на командата да обнови състоянието на процеса или не, се нарича commit point (точка за фиксация на резултатите). Ако процесорът съхранява резултатите на командата, т.е. тя не е предизвикала изключение, то тази команда се определя като “закомичена” (зафиксирана).

      За да разберем къде трябва да бъде разположена точката за фиксация на резултатите CP, ще припомним главните етапи в командния цикъл (вижте още раздел 5.3):

1.       Извличане на командата от паметта ;

2.       Декодиране на командата ;

3.       Изпълнение на операцията ;

4.       Запис на резултатите в регистри или в паметта.

      Разбирането е, че точката CP трябва да бъде намерена преди да се запишат резултатите, но към този момент вече следва да бъде известно генерира ли командата изключение или не. Изключение може да бъде генерирано по време на всеки един от горните етапи, например:

1.       Ако възникне грешка в паметта при извличане на командата ;

2.       Ако при декодиране се установи неизвестен код на операцията ;

3.       Ако при изпълнение на операцията се установи деление с нула ;

4.       Ако възникне грешка в паметта при опит за запис на резултатите.

      Очевидно е, че реализацията на точни прекъсвания не е възможна, докато не бъде решен проблемът със записа на резултатите в паметта:

·         Не следва да се фиксира командата и да й се разрешава да записва резултати в паметта, докато не стане ясно, че командата е генерирала изключение ;

·         Не е възможно да се разбере, че изключение не е генерирано, без да се запишат резултати (за това трябва да се получи потвърждение от MMU, че записът е завършил успешно).

      Читателят вероятно разбира, че проблемът със записа в паметта е труден за разрешаване, ето защо в много процесори се реализират “почти точни” прекъсвания, което означава, че точни са всички прекъсвания, освен изключенията, предизвикани от грешки в паметта при запис на резултати. При това условие, точката за фиксация на резултатите CP, се намира между третия и четвъртия етапи на командния цикъл. Важно е да се помни, че програмният брояч трябва да се модифицира задължително след точката за фиксация CP. При това положение модифицирането му не зависи от това дали командата е фиксирана или не – в него се записва или адресът на следващата команда, или векторът за прекъсване, или съдържанието на регистър РАВ.

Точни прекъсвания в процесори с паралелно изпълнение на командите

      В съвременни условия вече не се използват процесори с последователно изпълнение на машинни команди. Въпреки множеството предимства на съвременните конвейерни процесори, които се определят като процесори с паралелно изпълнение на машинните команди, техният команден конвейер значително усложнява реализацията на точното прекъсване.

      В процесор с последователно изпълнение на командите етапите на командния цикъл зависят един от друг. Например, програмният брояч, който съдържа адреса на следващата команда, в началото се използва за извличане на командата, а после в етапа на нейното изпълнение той се модифицира. В последствие, ако текущата команда бъде зафиксирана, програмният брояч се обновява в етапа на запис на резултатите. Всичко това води до положение, което не позволява да бъде извлечена следващата команда, докато текущата не завърши и последния етап на своето изпълнение и не обнови съдържанието на програмния брояч.

      Процесор с команден конвейер може да се получи от този с последователно изпълнение, само ако се постигне независимост един от друг между отделните етапи в командния цикъл. За целта резултатите от всеки етап, освен от последния, се съхраняват в допълнителни междинни регистри, които по същество представляват фиксатори на отделните степени в един конвейер (конвейерни регистри) (вижте раздел 5.3.2 и фигура 5.3.2.2):

1.       Резултатът от извличането (самата машинна команда) се съхранява в регистър, разположен между етапа извличане и етап декодиране ;

2.       Резултатът от декодирането (кода на операцията, стойността на операндите, адреса за резултата) се съхранява в регистър, разположен между етапа декодиране и етап изпълнение на операцията ;

3.       Резултатите от изпълнението (новата стойност на програмния брояч за условен преход, резултат изчислен в АЛУ и пр.) се съхраняват в регистър, разположен между етапа изпълнение и етап на запис на резултатите ;

4.       В последния етап не е необходим конвейерен регистър, тъй като и без това резултатите се записват или в системен регистър или в паметта.

      Ето как работи получения конвейер:

 

Такт

Програмен

брояч

Извличане на

команда

Декодиране

Изпълнение

Запис на

резултатите

1

0xxx00

К1

 

 

 

2

0xxx04

К2

К1

 

 

3

0xxx08

К3

К2

К1

 

4

0xxx0C

К4

К3

К2

К1

5

0xxx10

К5

К4

К3

К2

 

      Обърнете внимание на следното:  за да се осигури точно прекъсване, първата команда няма право да модифицира съдържанието на програмния брояч по-рано от четвъртия такт. За да се поправи това несъответствие, съдържанието на програмния брояч трябва да се пренесе зад точката на фиксиране (ще предположим, че тя се намира между трети и четвърти етапи):

 

Такт

Програмен

брояч

Извличане на

команда

Декодиране

Изпълнение

Запис на

резултатите

1

0xxx00

К1

 

 

 

2

0xxx00

 

К1

 

 

3

0xxx00

 

 

К1

 

4

0xxx04

К2

 

 

К1

5

0xxx04

 

К2

 

 

 

      Вижда се, че производителността на процесора е намаляла. Решението на проблема изисква реализацията на още един програмен брояч. Първият от тези броячи ще се намира в началото на конвейера и ще указва адреса за извличане на командата. Вторият брояч ще се намира в края на конвейера и ще указва адреса на онази команда, която следва да бъде зафиксирана. Първият програмен брояч се нарича “спекулативен” (СПБ), а вторият – “архитектурен” (АПБ). Най-често спекулативният програмен брояч фактически не се реализира. Той е вграден в предсказателя на преходите.

 

Такт

С П

брояч

Извличане на

команда

Декодиране

Изпълнение

Запис на

резултатите

А П

брояч

1

0xxx00

К1

 

 

 

0xxx00

2

0xxx04

К2

К1

 

 

0xxx00

3

0xxx08

К3

К2

К1

 

0xxx00

4

0xxx0C

К4

К3

К2

К1

0xxx04

5

0xxx10

К5

К4

К3

К2

0xxx08

 

      Изпълняват се следните действия:  командата, премествайки се между етапите, тегли със себе си адреса, от който е била извлечена (съдържанието на СПБ). Преди точката за фиксация на резултатите, процесорът проверява дали не е пристигнала външна ЗП, или дали командата не е генерирала изключение, а също така сравнява нейния адрес с адреса в АПБ. В резултат са възможни следните действия:

·         Ако е прието външно прекъсване, командата се зафиксира (закомичва), но адреса на следващата команда се записва не в АПБ, а в РАВ. В АПБ се записва адреса на вектора на приетото прекъсване ;

·         Ако е възникнало изключение, командата не се закомичва, вместо това в АПБ се записва адресът на вектора на генерираното изключение. Адресът на командата се записва в РАВ ;

·         Ако адресът на командата не е равен на съдържанието на АПБ, тя не се закомичва. Ако пък адресът на командата е равен на съдържанието на АПБ и не е било генерирано изключение, процесорът фиксира командата и обновява АПБ (записва адреса за преход, ако е команда за условен преход, а в случай на друга команда, просто го инкрементира).

      Естествено е да запитаме защо адресът на командата може да не бъде равен на съдържащият се в АПБ?  Ще анализираме тази ситуация – нека сме включили току що компютъра и той извлича първата команда, според таблицата на прекъсванията. Тази команда е команда за преход например към адрес 0ххх1234. Конвейерът сработва така:

 

Такт

С П

брояч

Извличане на

команда

Декодиране

Изпълнение

Запис на

резултатите

А П

брояч

1

0xxx00

JUMP 0xxx1234

 

 

 

0xxx00

2

0xxx04

К2

JUMP 0xxx1234

 

 

0xxx00

3

0xxx08

К3

К2

JUMP 0xxx1234

 

0xxx00

4

0xxx0C

К4

К3

К2

JUMP 0xxx1234

0xxx1234

        Адресът на команда К2 в 4-ти такт е 0ххх04. Така той не е равен на съдържащият се в АПБ. Това е така, защото условният преход е бил предсказан невярно.

5

0x1234

К666

 

 

 

0xxx1234

6

0x1238

К667

К666

 

 

0xxx1234

7

0x1240

К668

К667

К666

 

0xxx1234

8

0x1244

К669

К668

К667

К666

0xxx1238

 

      Показаният 4 степенен конвейер е твърде елементарен. Има команди, които изискват за своето изпълнение повече от един такт, и дори прост микроконтролер може да ги завършва не в този ред, в който те са били заредени, при това осигурява точно прекъсване. Общият принцип за организиране на прекъсванията обаче остава такъв, какъвто беше представен.

Точни конвейерни прекъсвания

      Обработката на прекъсванията в един конвейерен процесор се оказва значително по-сложна по причина на това, че съвместеното изпълнение на машинните команди затруднява определянето на възможностите за безопасно изменение на състоянието му в произволен момент. В конвейерния процесор командата се изпълнява поетапно и нейното завършване настъпва няколко такта след зареждането й. Още в процеса на изпълнение на отделните етапи командата може да промени състоянието на процесора. Възникващото междувременно прекъсване може да принуди процесора да прекъсне изпълнението на още не завършилите команди, намиращи се в конвейера.

      Както и в обикновените процесори, така и в конвейерните, съществуват два основни проблема при осъществяване на прекъсване:

1.       Прекъсванията могат да възникват в процеса на изпълнение на дадена команда ;

2.       Необходим е механизъм за връщане от прекъсване в условията на недовършено изпълнение на заварените в конвейера команди.

      Нека си припомним нашия обикновен конвейер, разгледан като примерен в пункт 5.3.2. В който прекъсване по причина на отсъствие на страница от виртуалната паметта не може да се генерира преди етапа обръщение към паметта (етап ФР (Фиксиране на резултата) – вижте определението на етапите в конвейера). В момента на възникване на това прекъсване, в процес на изпълнение вече ще се намират няколко команди (вижте времедиаграмата от фигура 5.3.2.3). Тъй като подобно прекъсване трябва да осигури връщане и продължение на прекъснатата програма, а по време на обработката на прекъсването процесорът ще се превключи към друг процес (от операционната система), то е необходимо надеждно да се изчисти конвейера и да се съхрани състоянието му такова каквото е било, за да може повторното изпълнение на командата след връщане от прекъсване да се осъществи при коректно състояние на машината. Обикновено това изисква съхранение на адреса на командата, предизвикала прекъсването, който е функция на текущото съдържание на програмния брояч. Ако извлечената след връщането от прекъсване команда не е команда за преход, то се съхранява последователността от заредените в конвейера команди, което е типичният случай. Ако обаче командата е за преход, то ние знаем, че в зависимост от прогнозата за прехода се извличат команди от клона на целевия адрес или от следващия по ред адрес. Когато настъпва прекъсване, за коректно съхранение на състоянието на процесора следва да бъде изпълнено следното:

1.      В последователността от команди, която постъпва в конвейера, принудително се вмъква командата за преход ;

2.      Докато се изпълнява процедурата за прекъсване се подтискат всички искания за запис на командата, предизвикала прекъсването, а така също и на всички следващи я в конвейера команди. Тези действия са насочени към предотвратяване на всички изменения в състоянието на процесора от команди, които не са завършили своето изпълнение до началото на обработката на прекъсването ;

3.      След предаване на управлението на обслужващата програма, последната незабавно следва да съхрани съдържанието на програмния брояч, което представлява адреса за връщане от прекъсването.

Ако се използват механизмите на задържаните (отложените) преходи, състоянието на процесора вече е невъзможно да се възстанови с помощта на един програмен брояч, тъй като в процеса на възстановяване на командите, в конвейера могат да се окажат съвсем непоследователни. В частност, ако командата, която е предизвикала прекъсването, се намира в слот на задържан преход (вижте определението на фигура 5.3.2.11) и преходът е бил изпълним, то е необходимо отново да се повтори изпълнението на командата, поставена в слота на задържане плюс командата, намираща се по целевия адрес на командата за преход. Самата команда за преход е вече изпълнена, така че нейното повторно изпълнение на е необходимо. При това адресите на командите в слота на задържания преход и целевият адрес на командата за преход естествено не са последователни. Ето защо е необходимо да се съхраняват и възстановяват няколко програмни брояча. Броят на програмните броячи е с единица по-голям от дължината на слота на задържане, т.е. от броя на прескочените команди (вижте определението в точка 4, предхождаща фигура 5.3.2.11). Тези действия се отнасят към по-горе посоченият трети по ред етап при осъществяване на прекъсването.

 

     След обработката на прекъсването специализирани команди осъществяват връщане от прекъсване чрез възстановяване на съдържанието на програмните броячи и потока от команди. Ако конвейерът може да бъде възстановен така, че командите, които непосредствено са предхождали командата, предизвикала прекъсването, могат да завършат изпълнението си, а следващите я команди могат да бъдат повторно заредени за изпълнение, тогава казват, че конвейерът осигурява точно прекъсване.

 

В идеалния случай, командата предизвикала прекъсването не е длъжна да изменя състоянието на процесора. Освен това за коректна обработка на някои типове прекъсвания се изисква, командата предизвикала прекъсването, да няма странични ефекти. За други типове прекъсвания, например за прекъсване при изключителни ситуации с плаваща запетая, командата предизвикваща прекъсването в някои процесори записва своите резултати още преди момента, когато прекъсването може да бъде обработено. В такива случаи апаратурата е длъжна да бъде в състояние да възстанови операндите-източници, даже ако местоположението на резултата на командата съвпада с местоположението на един от операндите-източници.

      Поддържането на точното прекъсване в много системи представлява задължително изискване, а в други би било особено желателно, тъй като способства за опростяване на интерфейса на операционната система. Като минимум в процесори със странична организация на паметта или с реализация на цифрова аритметика по стандартите на IEEE, средствата за обработка на прекъсванията трябва да осигуряват точното прекъсване или изцяло с апаратни средства, или с помощта на известна поддръжка от страна на програмните средства. Проблемите на точното прекъсване са допълнително разгледани в пункт 6.4.4.

      Необходимостта от реализация на точно прекъсване понякога се оспорва по причина на някои проблеми, които усложняват повторното стартиране на командите. Рестартът на командите е сложен поради това, че командите могат да изменят състоянието на процесора преди момента, в който те гарантирано завършват своето изпълнение. По някога гарантираното завършване на командата се нарича конвейерният етап фиксация на резултатите. Тъй като командите в конвейера могат да бъдат взаимно зависими, блокировката на изменението на състоянието на процесора може да се окаже непрактична, ако конвейерът продължава да работи. По този начин, с увеличаване степента на конвейеризация, възниква необходимост за отхвърляне на всяко изменение на състоянието, което може да се изпълни до фиксиране на резултата. За щастие в простите конвейери такива проблеми не възникват. Възможните причини за прекъсване в отделните етапи на един обикновен конвейер са следните:

·         Етап ДК (доставка на команда). Настъпва поради грешка при обръщение към страница в паметта при извличане на команда ; неизравнено обръщение към паметта ; нарушение на защитата на паметта.

·         Етап АО (анализ и декодиране на командата). Настъпва при откриване на неопределен или забранен (в смисъла на нивото на привилегия за командата) код на операцията.

·         Етап ИО (изпълнение на операцията). Генерира се от аритметичните микропрограми.

·         Етап ФР (фиксиране на командата). Настъпва поради грешка при обръщение към страница в паметта при запис на данни ; неизравнено обръщение към паметта ; нарушение на защитата на паметта.

Поддържане на точното прекъсване

      Друг проблем генерират машинни команди, които имат дълъг алгоритъм, т.е. продължително време на изпълнение. Ще го поясним чрез следната последователност от команди:

DIVF         F0, F2, F4

ADDF       F10, F0, F8

SUBF       F12, F12, F14

      Тази последователност изглежда обикновена, тъй като в нея отсъства всякакви зависимости. Тя обаче довежда до нови проблеми свързани с това, че е възможно по-рано заредената команда да завърши изпълнението си по-късно от по-късно заредена команда, т.е. да закъснее много със своето изпълнение. В приведения текст може да се очаква, че командите ADDF и SUBF ще завършат изпълнението си преди командата DIVF. Основанието за това е дълбоката конвейеризация на операция деление (вижте задръжките в таблица 5.3.2.2 и фигура 5.3.2.13). Този ефект е типичен за командни конвейери голямо време за изпълнение и се нарича непоследователно завършване (завършване извън установения ред – out-of-order-completion). В този случай например, ако команда DIVF генерира аритметично прекъсване в момент след като команда ADDF е завършила, процесорът не може да реализира точно прекъсване на ниво хардуер. В действителност, тъй като командата ADDF безвъзвратно губи един от своите операнди, защото на негово място фиксира резултата, става невъзможно възстановяването на състоянието, което е било преди изпълнение на команда DIVF, даже с програмни средства.

      Съществуват четири възможно подхода за работа в условия на преждевремено завършване на командите. Първият подход се характеризира с игнориране на проблема, като в същото време предлага механизъм за неточно прекъсване. Този подход се е прилагал в процесорите от 70-те години на миналия век и все още се прилага в някои суперкомпютри, в които някои класове прекъсвания са забранени или се обработват от апаратурата без да се спира конвейера. Този подход обаче трудно може да се използва в системи с виртуална памет и в стандарта на IEEE за операции с плаваща запетая, тъй като те изискват реализация на точно прекъсване чрез комбиниране на апаратни и програмни средства. В други процесори този проблем се решава чрез въвеждане на два режима за изпълнение на командите – “бърз”, но с възможно неточно прекъсване и “бавен”, с гарантиране на осъществяването на точно прекъсване.

      Вторият подход се състои в буфериране на резултатите от операциите до момента на завършване на изпълнението на всички команди, които предхождат дадената (тази, която закъснява). Някои машини използват този подход, но той струва все по-скъпо, ако времевите разлики в изпълненията на различните команди са твърде големи, тъй като обема на резултатите, които следва да се буферират нараства значително. Нещо повече, резултатите от тази буферирана опашка следва да се прехвърлят в съответния момент в регистровата памет, за да се осигури непрекъснато зареждане на нови команди. Всичко това изисква голямо количество логически схеми за сравнение и многовходови мултиплексори. Има два варианта за реализация на този подход. Първата реализация използва буфер, които се нарича буфер на историята (history file) (в процесори CYBER). Буферът на историята проследява в своята дълбочина първоначалното съдържание на регистрите. Ако възникне прекъсване и състоянието на процесора е необходимо да се проследи назад до точката, предхождаща нечие преждевременно завършване, то тогавашното съдържание на регистрите може да бъде възстановено от съдържанието на този буфер. Подобна методика се е използвала също при реализация на автоинкрементната и автодекрементната адресации в машините VAX. Вторият вариант на реализация използва буфер на бъдещето (future file). Този буфер съхранява новите стойности на регистрите. Когато всички предходни команди са завършили, основният регистров файл се обновява със стойностите от този буфер. При прекъсване основният регистров файл съхранява точното значение на регистрите, което опростява организацията му.

      Третият подход, който се използва, се състои в това, че в редица случаи се разрешава неточно прекъсване, но заедно с това се съхранява достатъчно информация, за да може обслужващата прекъсването програма да може да изпълни точната последователност на прекъсването. Това предполага наличие на информация за намиращите се в конвейера команди и за техните адреси. Тогава след обработката на прекъсването, програмното осигуряване завършва изпълнението на всички команди, предхождащи последно успялата да завърши команда, а след това потокът може да бъде пуснат отново. Нека разгледаме един от най-лошите случаи:

Команда №1 ;                Дълга команда, която предизвиква прекъсване

Команда №2,                 Последователност от команди,

Команда №3,                 чието изпълнение не е завършило

 … … … …

Команда №(n-1) ;

Команда №n ;                Команда, чието изпълнение е завършило.

      Имайки адресите на всички команди в конвейера, както и адреса за връщане от прекъсване, програмното осигуряване може да определи състоянието на Команда №1 и Команда №n. Тъй като последната е завършила изпълнението си, процесорът би искал да продължи с изпълнението на следващата Команда №(n+1). След обработка на прекъсването програмното осигуряване е длъжно да моделира изпълнението на командите от №1 до №(n-1). Тогава е възможно да се извърши връщане от прекъсване към Команда №(n+1). Ще припомним, че Команда №n е от преди това изпълнена. Най-голямата неприятност на този подход се дължи на усложнения в обслужващата програма. За обикновени конвейери обаче съществуват облекчения. Ако всички команди от №2 до №n са целочислени, тогава ние просто знаем, че ако е завършила команда №n, то всички команди от №2 до №(n-1) са също напълно завършили! Следователно е необходимо да се обработи само операцията с плаваща запетая. За да се направи тази схема работеща, броят на операциите с плаваща запетая, изпълняващи се съвместно, следва да бъде ограничен. Например, ако се допуска съвместно изпълнение само на две операции, то само прекъснатата команда ще трябва да се завършва с помощта на програмни средства. Това ограничение може да понижи потенциалната пропускателна способност, ако конвейерът с плаваща запетая е достатъчно дълъг, или ако има значителен брой функционални устройства. Такъв подход, позволяващ да се съвместява изпълнението на целочислените операции с такива с плаваща запетая, се използва в процесорите SPARC.

      Четвъртият подход представлява хибридна схема, позволяваща да продължава зареждането в конвейера на команди само ако е известно, че всички команди, които предхождат току що заредената, ще завършат без прекъсване. Тази логика гарантира, че в случай на възникване на прекъсване ни една следваща след нея команда няма да завърши, но всички предхождащи я ще завършат. Понякога това означава, че се налага вмъкване на задръжка в конвейера, за да се постигне точно прекъсване. За да бъде тази схема работеща, е необходимо функционалните устройства с плаваща запетая да могат да определят възможността за поява на прекъсване по време на ранните етапи от изпълнението на командите, така че да бъде предотвратено завършването на следващите команди. Тази логика се използва например в процесорите на MIPS, (R2000/R3000 и R4000).

      Някои компютърни системи са проектирани да осъществяват точно прекъсване за определен тип обикновени и системни прекъсвания, а за друг тип – неточно прекъсване. Например, точно прекъсване за входно-изходни грешки и неточно прекъсване за системни, предизвикани от фатални ситуации в програмния код, особено в случаи, когато се дели на нула, защото тогава няма никакъв смисъл процеса да се стартира повторно. Някои процесори имат специален бит, установяването на който може да застави процесора да изпълнява само точно прекъсване. Недостатък на този подход е задължението на процесора да поддържа дублиращо копие на съдържанието на всички регистри, за да може да възстановява състоянието във всеки момент. Всички тези натоварващи апаратурата разходи влияят негативно на производителността на системата.

      Някои суперскаларни процесори, например тези от фамилията х86, поддържат точно прекъсване, за да гарантират коректната работа на старо програмно осигуряване. За целта те поддържат в процесора сложна логическа апаратура. Тя гарантира, че с пристигането на ЗП от контролера на прекъсванията, на всички машинни команди до определена позиция се разрешава да завършат изпълнението си, а на всички команди след тази позиция не се разрешава да въздействат на състоянието на машината. Този подход води до значително усложняване на схемата на процесора и до увеличаване на времето за осъществяване на прекъсването. Ако за осигуряване на съвместимостта не е необходимо точно прекъсване, то вместо сложната апаратура може да се вгради кеш памет с увеличен обем, с което ще се увеличи бързодействието на процесора. В същото време неточното прекъсване съществено усложнява ОС и забавя нейната работа, ето защо е трудно да се каже, кой от подходите е наистина най-добър.

 

 

 

Следващият раздел е:

 

5.4.6.  Основни функции на операционната система