Последната актуализация на този раздел е от
2020 година.
5.3.7 Апаратни средства, поддържащи висока степен на разпаралелване
Методи,
подобни на методите за разгъване на цикли и планиране на трасетата, могат да се
използват за увеличаване на степента на достъпния паралелизъм, когато
поведението на условните преходи е достатъчно добре прогнозируемо по време на
компилиране на програмите. Ако поведението на преходите не е известно, само
техниката на компилатора може да се окаже недостатъчна за изявяване на желана
висока степен на паралелизъм на ниво команди. Тук ще бъдат представени два
метода, които могат да помогнат за преодоляването на споменатите ограничения.
Същността на първия метод се състои в разширяване на системата от машинни
команди с команди за условен преход или с предикатни команди. Команди от този
тип могат да се използват за ликвидация на условните преходи и помагат на
компилатора да премества команди през точките на условните преходи. Условните
команди увеличават степента на паралелизъм на ниво команди, но имат съществени
ограничения. За използване на високата степен на паралелизъм се прилага още
спекулативно изпълнение, метод, който намалява задръжките в конвейерите,
свързани със зависимостите по управление.
Разбирането, което
лежи в основата на условните команди, е достатъчно просто: командата се обръща
към някакво условие, чиято проверка представлява част от изпълнението на
командата. Ако условието е изпълнено (е истинно), то командата се изпълнява
нормално; а ако условието не е изпълнено, т.е. изходът от проверката е “лъжа”,
то изпълнението на командата е като че ли тя е празна, т.е. команда NOP.
Единственият ефект който остава е загубеното време за нейното извличане и за
проверката на условието. В по-развитите в структурно отношение архитектури
съществуват различни форми на условните команди. Най-общ е примерът за условна
команда, която прехвърля съдържанието на един регистър в друг, ако условието е
“истина”. Такава команда може да се използва за пълно отстраняване на условните
преходи в тривиални последователности на програмния код. Нека например, да
разгледаме следния оператор:
if (A=0)
{S=T} ;
Предполагайки,
че регистрите R1, R2 и R3 съхраняват стойностите на променливите A, S и T съответно, ще
представим кода на този оператор с команда за условен преход и с команда за
условно прехвърляне. Кодът с използване на команда за условен преход е
следният:
BEQZ R1, L
MOVE R2, R3
L: … …
Използвана
е командата за условно пренасяне (MOVE), която изпълнява пренасяне на
съдържанието на регистър R3 в регистър R2 само когато съдържанието на регистър
R1 е равно на нула. Същото можем да реализираме със следната команда:
CMOVZ R2,
R3, R1 ;
Условната
команда преобразува зависимостта по управление, в зависимост по данни. Такова преобразуване
се използва още във векторните процесори, където се нарича if-преобразование). В
конвейерния процесор това преобразование позволява да се премести точката (в
която трябва да се разреши зависимостта) от началото на конвейера (където тя се
разрешава за условните преходи) в края на конвейера, където се извършва запис в
регистър.
Пример за използване на командата за условно пренасяне представлява още функцията за изчисление на абсолютната стойност в следния оператор:
if (B<0) {A=-B) else {A=B} ;
Този оператор if
може да бъде реализиран с две команди за условно пренасяне или с команда за
безусловно пренасяне (А=В), след която следва команда за условно пренасяне
(А=-В).
Условните
команди могат да се използват още за подобряване на планирането в
суперскаларните или в VLIW-процесорите. По-долу е приведен пример за
суперскаларен процесор с едновременно подаване за изпълнение на повече от 2
команди. При това във всеки такт може да бъде подавана комбинация, в която се
съдържа една команда за обръщение към паметта и една команда за АЛУ и само една
команда за условен преход:
LOADW R1, 40(R2) , ADD R3, R4, R5
;
ADD R6, R3, R7 ;
BEQZ R10, L ;
LOADW R8,
20(R10) ;
LOADW R9,
0(R8) ;
Тази
последователност губи слота на операция обръщение към паметта по време на
втория такт и се задържа по причина на зависимост по данни, ако условният
преход не изпълним, тъй като втората команда LOAD след прехода зависи от
предидущата команда за зареждане. Ако е достъпен условният вариант на командата
за зареждане, то командата LOAD R8,20(R10), непосредствено следваща след
прехода, може да бъде пренесена във втория слот за зареждане. Това ще намали
времето за изпълнение с няколко такта, тъй като се отстранява един слот за
зареждана на команда и намалява задръжката на конвейера за последната команда в
последователността.
За успешно
използване на условните команди в подобни примери, семантиката на командата
трябва да определя командата по такъв начин, че да няма страничен ефект, когато
условието не се изпълнява. Това означава, че ако условието не се изпълнява,
командата не трябва да записва резултат, а така също не трябва да предизвиква
изключителна ситуация. Както показва горният пример, способността да не се
предизвиква изключителна ситуация е достатъчно важна: ако например регистър R10
съдържа нула, то командата LOAD R8,20(R10), изпълнявайки се безусловно,
вероятно ще предизвика изключителна ситуация по защита на паметта (обръщението
е към твърде малък адрес). А такава изключителна ситуация не би трябвало да
възниква в програмата. Именно тази вероятност за възникване на изключителни
ситуации не дава възможност на компилатора да премести командата за зареждане
на регистър R8 преди командата за условен преход. Разбира се, ако условието за
преход е изпълнено, командата за зареждане все още може да предизвика
изключителна ситуация (например при обръщение към не принадлежаща на програмата
страница). В този случай апаратурата е длъжна да възприеме прекъсването, тъй
като тя знае, че управляващото условие е истинно.
Условните команди са определено полезни за реализация на къси алтернативни потоци (имат се предвид блоковете в двата клона). Все пак полезността на условните команди съществено се ограничава от няколко фактора:
·
Анулируеми условни команди, т.е.
команди, чието условие е неизпълнено (“лъжа”). Изпълнението на тези команди все
пак отнема определено време. Затова пренасянето на командата през командата за
условен преход и превръщането й в условна забавя програмата винаги, когато
пренесената команда не се изпълнява нормално. Важно изключение от това правило
възниква, когато тактовете, използвани от пренесената неизпълняваща се команда,
биха били във всички случаи празни. Пренасянето на командата през команда за
условен преход се основава на предположението за посоката на прехода. Условните
команди опростяват реализацията на такъв пренос, но не отстраняват времето за
изпълнение, което при неправилен преход ще е загубено ;
·
Условните команди са
най-полезни, когато условието може да бъде изчислено по-отрано. Ако условието и
условният преход не могат да бъдат отделени един от друг (поради зависимости по
данни при определени условия), то условната команда няма да помогне, въпреки че
все още може да бъде полезна, тъй като тя задържа момента, когато условието
става известно почти до края на конвейера ;
·
Използването на условни команди
е ограничено, когато в управлявания поток е въвлечена повече от една проста
алтернативна последователност от команди. Например, при пренос на командата
през две команди за условен преход, е необходимо тя да остава зависима и от
двете условия, което изисква спецификация в командата и на двете условия (малко
вероятна възможност), или вмъкване на допълнителни команди за изчисление на
конюнкцията от условията ;
·
Условните команди могат да
причиняват загуби в скоростта в сравнение с безусловните команди. Това може да
се прояви в голям брой тактове, необходими за изпълнение на такива команди, или
в намаляване на общата синхронизираща честота. Ако условните команди са
по-скъпи от гледна точка на скоростта за изпълнение, то те следва да се
използват осмислено.
По тези причини в много съвременни процесори се използва малък брой условни команди, от които най-популярни са командите за условно пренасяне, въпреки че някои от тях включват условни варианти на повечето команди.
Поддържаното от апаратурата спекулативно изпълнение позволява на процесора да изпълни дадена команда преди да бъде определена посоката на условния преход, от която тя зависи. Това снижава загубите, които възникват, когато в програмата съществуват зависимости по управление. За да поясним защо спекулативното изпълнение е полезно, ще разгледаме примерен програмен код, който реализира последователно инкрементиране на елементите на свързан списък:
for (ppp=head; ppp <> nil; *ppp=*ppp.next) {
*ppp.value = *ppp.value+1 ;
}
Подобно на
други цикли for, които ние вече разглеждахме, разгъването на този
цикъл не увеличава степента на достъпния на ниво команди паралелизъм.
Действително, след разгъването всяка разгъната итерация ще съдържа оператор if
за излизане от цикъла. По-долу е приведена командна последователност при
предположението, че стойността на променливата head се намира в регистър
R4 (head=(R4)), който се използва за съхранение на стойността на
променливата ppp,
и че всеки елемент от списъка съдържа поле за стойността и поле за указател.
Проверката се помества отдолу така, че при всяка итерация на цикъла, да се
изпълни само един преход.
JUMP looptest
start: LOADW
R5, 0(R4)
ADDI R5, R5, #1
STOREW 0(R4), R5
LOADW R4,
4(R4)
looptest: BNEZ R4, start
Ако разгънем
този цикъл един път ще можем да видим, че това не помага:
JUMP looptest
start: LOADW
R5, 0(R4)
ADDI R5, R5, #1
STOREW 0(R4), R5
LOADW R4,
4(R4)
BEQZ R4, end
LOADW R5,
0(R4)
ADDI R5, R5, #1
STOREW 0(R4), R5
LOADW R4,
4(R4)
looptest: BNEZ R4, start
end:
Даже
прогнозирайки посоката на прехода, ние не можем да изпълним с припокриване
команди от две различни итерации на цикъла, така че условните команди тук не
помагат. Съществуват няколко сложни моменти за изявяване на паралелизма в този
разгънат цикъл:
·
Първата команда в итерацията на
цикъла (LOADW R5,0(R4)) зависи по управление и от двата условни прехода.
По този начин командата не може да се изпълни успешно (и безопасно), докато не
станат известно изходите от командите за преход ;
·
Втората и третата команда в
итерацията на цикъла зависят по данни от първата команда на цикъла ;
·
Четвъртата команда във всяка
итерация (LOADW R4,4(R4)) зависи по управление от двата прехода и
антизависи от непосредствено предхождащата я команда STOREW ;
·
Последната команда в итерацията
на цикъла зависи от четвъртата. Взети заедно тези условия означават, че ние не
можем да съвместяваме изпълнението на никакви команди между последователни
итерации на цикъла! При разгънат цикъл съществува малка възможност за
съвместяване чрез преименуване на регистрите или с апаратни или с програмни
средства, така че второто зареждане повече да не е антизависима от командата за
запис и ще може да бъде преместена по-нагоре в текста.
В
алтернативния вариант, при изпълнение по предположение, че преходът няма да се
изпълнява, можем да се опитаме да съвместим изпълнението на последователни
итерации на цикъла. Действително, това наистина е онова, което прави
компилаторът при планиране на трасетата. Когато посоките на преходите могат да
се прогнозират по време на компилация и компилаторът може да намери команди,
които може безопасно да премести преди точката на прехода, тогава решението,
базиращо се на технологията на компилатора, е идеално. Тези две условия са
ключовите ограничения за изявяване на паралелизма на ниво команди статически и
помощта на компилатора. Отново разглеждаме разгънатия по-горе цикъл. Преходът е
трудно предсказуем, тъй като честотата, с която той е изпълним, зависи от
дължината на списъка, която се контролира. Освен това, ние не можем безопасно
да пренесем командата за зареждане през прехода, тъй като, ако съдържанието на
регистър R4 е nil ((R4)=nil), то командата за зареждане на дума (word),
която използва регистър R4 като базов, гарантирано ще доведе до грешка и ще
генерира изключителна ситуация чрез системата за защита на паметта. В много
системи стойността nil се реализира с помощта на указател на
неизползваема страница от виртуалната памет, което осигурява така наречения
“капан” (trap) при обръщение към нея. Понятието “капан” е специфично за
системата за прекъсване, която ще разглеждаме в тази глава по-късно. Това
решение е добро за универсална схема за откриване на указатели на nil,
но в дадения случай то не помага много, тъй като ние можем регулярно да
генерираме тази изключителна ситуация, и цената на обработката на
изключителната ситуация плюс унищожаването на резултатите от изпълнението по
предположение, ще бъде огромна.
За да
преодолее тези усложнения, процесорът трябва да притежава специални апаратни
средства за поддръжка на изпълнението по предположение. Този начин на
изпълнение позволява на процесора да изпълнява команда, която може да бъде
зависима по управление и да избягва всякакви последствия от изпълнението на
тази команда (включително и изключителни ситуации), ако се окаже, че в
действителност командата не следва да се изпълнява. Така изпълнението по
предположение, подобно на условните команди, позволява да се преодолеят два
сложни момента, които могат да възникнат при по-ранно изпълнение на командата:
възможност за поява на изключителна ситуация и ненужно изменение на състоянието
на процесора, предизвикано от изпълнението на командата. Освен това,
механизмите за изпълнение по предположение позволяват да изпълняваме командата
даже до момента за проверка на условието в команда за условен преход, което не
е възможно за условните команди. Разбира се, апаратната поддръжка на
спекулативното изпълнение е достатъчно сложна и изисква значителни апаратни
разходи.
Един от
подходите, който е добре изследван и продължава да се прилага, се състои в
обединяването на апаратните средства за динамично планиране с тези,
предназначени за спекулативното изпълнение. В определена степен тази идея е
била реализирана още в споменатия по-рано процесор IBM-360/91, в който
средствата за прогнозиране на посоката на прехода са се използвали за извличане
на команди и разпределението им по станциите за резервиране. Механизмите,
допускащи спекулативно изпълнение, отиват по-нататък и позволяват
действителното изпълнение на тези, а също и на други команди, зависещи от
спекулативно изпълняваните команди. Както и за алгоритъма на Томасуло (вижте пункт 5.3.3, буква Б2), тук ще поясним спекулативното
изпълнение чрез пример с устройства за плаваща запетая, но всичките идеи са
естествено приложими и за устройства с фиксирана запетая.
Апаратурата,
която реализира алгоритъма на Томасуло, може да бъде разширена за осигуряване
поддръжката на спекулативното изпълнение. За целта е необходимо да се отделят
средствата за преместване на резултатите на командите, които трябва да се
изпълнят спекулативно заради някоя команда, от механизма на действителното
завършване на командите. Имайки такова разделяне на функциите, ние можем да
допуснем изпълнение на командата и да прехвърляме нейните резултати към други
команди, без обаче да й позволяваме да обновява състоянието на процесора,
докато не разберем, че тя е следвало безусловно да бъде изпълнена. Използването
на заобикалящите връзки от своя страна също е подобно на спекулативното четене
на регистър, тъй като ние не знаем осигурява ли командата, която формира
съдържанието на регистъра-източник, коректен резултат до момента, когато
нейното изпълнение става безусловно. Ако спекулативното изпълнение на
дадена команда стане безусловно, то на
тази команда се разрешава да обнови регистровата или основната памет. Този
допълнителен етап в изпълнението на командата обикновено се нарича фиксиране на резултата (instruction commit).
Главната идея,
на която се основава реализацията на изпълнението по предположение
(спекулативното изпълнение), се заключава в разрешението за непоследователното
изпълнение на командите, но при строго спазване на реда за фиксиране на
резултатите и за предотвратяване на всяко безвъзвратно действие (например,
обновяване на състоянието или вземане на решение за обслужване на прекъсване)
до момента, когато резултатът на командата се фиксира. В обикновения конвейер
със зареждане на една команда в такт можеше да се гарантира, че резултатът на
командата се фиксира в реда, определен от програмата и само след проверка за
отсъстваща изключителна ситуация, причинявана от тази команда, просто чрез
поставяне на етапа запис на резултата в края на конвейера. Когато добавяме
обаче механизъм за изпълнение по предположение, ние следва да отделим процеса
на фиксация на резултата на командата, тъй
като той може да се осъществи значително по-късно, в сравнение с простия
конвейер. Добавянето към последователността от етапи в изпълнението на
командата на тази фаза (този етап) изисква някои изменения в последователността
от действия, а така също и в допълнителния набор от апаратни буфери,
съхраняващи резултатите от командите, които са завършили изпълнението си, но
резултатите им още не са фиксирани. Този апаратен буфер, който се нарича буфер за преподреждане, се използва също
и за предаване на резултати между командите, които могат да се изпълняват
спекулативно. Буферът за преподреждане предоставя допълнителни виртуални
регистри, точно както това правят станциите за резервиране в алгоритъма на
Томасуло, разширявайки по този начин регистровата памет. Буферът съхранява
резултата от някаква операция в интервала от време, започващ от момента на
завършване на операцията, свързана с тази команда, до момента на окончателното
фиксиране на резултатите на командата. Ето защо буферът за преподреждане
представлява източник на операнди за командите, както станциите за резервиране
осигуряват междинното съхраняване и предаване на операндите в алгоритъма на
Томасуло. Главното отличие се състои в това, че когато в алгоритъма на Томасуло
командата записва своя резултат, всяка следваща команда, подадена в конвейера,
ще извлича този резултат от регистровата памет. При спекулативното изпълнение
съдържанието на регистровата памет не се обновява докато командата не фиксира
резултата. По този начин, буферът за преподреждане доставя операнди в интервала
между края на изпълнението и фиксирането на резултатите на командата. Буферът
за преподреждане не прилича на буфера за запис в алгоритъма на Томасуло. В
нашия пример тук функциите на буфера за запис са интегрирани в буфера за
преподреждане само с цел опростяване. Тъй като последният отговаря за
съхраняване на резултатите до момента на техния запис в съответните регистри,
той изпълнява също така и функциите на буфер за зареждане.
Всеки ред в
буфера за преподреждане съдържа три полета: за типа на командата, за
местоназначението на резултата и за стойността. Полето за тип на командата определя
дали командата е за условен преход (за която не е необходимо местоназначение на
резултата), дали командата е за запис (която като местоназначение използва
адрес в паметта) или дали командата е за регистрова операция, чието
местоназначение е регистър. Полето за местоназначение съхранява номера (адреса)
на регистър, когато командата е за зареждане или за работа с функционално
устройство, или съхранява адрес на клетка от паметта, когато командата е за
запис в паметта. Полето на стойността съхранява резултата от операцията до
момента на фиксирането му. На следващата фигура 5.3.7.1 е показана обобщена
структура на процесор с буфер за преподреждане.
Фиг. 5.3.7.1. MIPS-устройствата
за работа с ПЗ със средства за спекулативно изпълнение
Буферът за преподреждане заменя напълно буферите за зареждане и за запис. Въпреки че функцията за преименуване в станцията за резервиране е заменена с буфера за преподреждане, все още ни е необходимо някакво място за буфериране на операцията (и на операндите) между момента на подаването им в конвейера и началото на изпълнението. Тази функция се изпълнява от регистровите станции за резервиране. Тъй като всяка команда има позиция в буфера за преподреждане до тогава, докато резултатът не бъде фиксиран, т.е. не бъде записан в регистър, то за тег на резултата се използва номерът на реда в буфера, а не номерът на станцията за резервиране. Това налага проследяването на номера на реда в буфера за преподреждане, съответстващ на командата, да се осъществява от станцията за резервиране.
В условията на
описаните механизми, изпълнението на командите преминава през следните етапи:
1.
Зареждане. В конвейера се зарежда поредната команда от опашката с
плаваща запетая. Командата стартира изпълнението си, ако има свободна станция
за резервиране и свободен ред в буфера за преподреждане. Извличат се и се
предават в станцията за резервиране операндите на командата, ако те се намират
в регистри или в буфера за преподреждане. Обновяват се полетата за управление,
индициращи използването на буфера. Определеният за резултата номер на ред в
буфера за преподреждане също се записва в станцията за резервиране, така, че
този номер може да се използва като тег, т.е. като отметка на резултата, когато
той се помества в CDB-шината (common data bus) (вижте фигура 5.3.3.2). Ако всички станции за резервиране са
запълнени, или ако е пълен буферът за преподреждане, зареждането на командата
се задържа, докато и в двата буфера не се появи достъпен ред.
2.
Изпълнение. Ако един или няколко операнда не са готови (отсъстват),
се прави проверка на CDB-шината и се очаква изчислението на стойността в
искания регистър. По време на този етап се проверява за наличие на конфликти от
тип RAW. Когато и двата операнда се окажат в станцията за резервиране, тогава се
преминава към изпълнение на операцията.
3.
Запис на резултата. Когато резултатът е готов и стане достъпен, той се
извежда върху CDB-шината заедно с тега на реда в буфера за преподреждане, който
е бил присвоен на командата по време на етапа зареждане. Така чрез CDB-шината
резултатът попада в буфера за преподреждане и във всички станции за
резервиране, които го очакват. Възможно е да се чете резултат от буфера за
преподреждане без да се използва CDB-шината, точно така, като централизираната
схема за управление (вижте обясненията, свързани с
фигура 5.3.3.1) чете резултати от регистрите, а не чрез изходната шина.
Станцията за резервиране се маркира като свободна.
4.
Фиксиране на резултата. Когато командата достигне върха на буфера за
преподреждане и нейният резултат присъства в буфера, съответният регистър
приема този резултат (или се изпълнява запис в паметта, ако операцията е запис
в паметта) и командата напуска буфера за преподреждане и вече не съществува в
него.
Когато завърши четвъртият етап на дадена команда, съответстващият й ред в буфера за преподреждане се нулира. За да не се променят номерата на редовете на буфера за преподреждане след етапа фиксиране, буферът се реализира във вид на циклическа опашка. Логическата структура на такъв буфер е представена на фигура 4.3.1. Ако буферът за преподреждане е пълен, зареждането на команда в конвейера се блокира, докато не се освободи поне един ред в този буфер.
Тъй като запис в регистър или в клетка от паметта не ще се извърши докато командата не се фиксира, процесорът може лесно да ликвидира всички спекулативно изпълнени действия, ако открие, че посоката на условния преход е прогнозирана невярно.
Ще разгледаме следния пример:
LOADD F6, 34(R2)
LOADD F2,
45(R3)
MULTD F0,
F2, F4
SUBD F8, F6, F2
DIVD F10, F0, F6
ADDD F6, F8, F2
Нека си
представим, че в горният текст, командата за условен преход BNEZ е
прогнозирана да изпълни преход в клона “лъжа”, така в конвейера ще бъдат
зареждани следващите я в текста команди. В този случай, командите, които
предхождат командата за условен преход и са били подадени по-рано, ще се
фиксират в реда, в който достигат изхода на буфера за преподреждане. Когато
изходът на буфера бъде достигнат от командата за условен преход и се окаже, че
прогнозата за прехода й е била грешна, тогава съдържанието на буфера се
изчиства и започва извличане на команди от другия клон на условната команда.
Междувременно, напредналите по отделните етапи команди (тези от горния текст),
са формирали представеното в следващите таблици състояние на устройствата с
плаваща запетая.
Таблица 5.3.7.1
Състояние на устройствата с плаваща запетая при изпълнение по
предположение
Станции за резервиране |
|||||||
Име |
Заетост |
Op |
Vj |
Vk |
Qi |
Qk |
Назначение |
Add_1 |
Не |
|
|
|
|
|
|
Add_2 |
Не |
|
|
|
|
|
|
Add_3 |
Не |
|
|
|
|
|
|
Mult_1 |
Не |
MULT |
Mem[45+Reg(R3)] |
Regs(F4) |
|
|
#3 |
Mult_2 |
Да |
DIV |
|
Mem[34+Reg(R2)] |
#3 |
|
#5 |
Буфер за преподреждане |
|||||
№ по ред |
Заетост |
Команда |
Състояние |
Местоназначение |
Стойност |
1 |
Не |
LOADD F6, 34(R2) |
Зафиксирана |
F6 |
Mem[34+Reg(R2)] |
2 |
Не |
LOADD F2, 45(R3) |
Зафиксирана |
F2 |
Mem[45+Reg(R3)] |
3 |
Да |
MULTD F0, F2, F4 |
Запис на резултата |
F0 |
(#2)*(#4) |
4 |
Да |
SUBD F8, F6, F2 |
Запис на резултата |
F8 |
(#1)-(#2) |
5 |
Да |
DIVD F10, F0, F6 |
Изпълнение |
F10 |
|
6 |
Да |
ADDD F6, F8, F2 |
Запис на резултата |
F6 |
(#4)+(#2) |
Състояние на регистъра на резултата |
|||||||||
Поле |
F0 |
F2 |
F4 |
F6 |
F8 |
F10 |
F12 |
… |
F30 |
Пореден # |
3 |
|
|
6 |
4 |
5 |
|
|
|
Заетост |
Да |
Не |
Не |
Да |
Да |
Да |
Не |
… |
Не |
Изключителните състояния в
подобни процесори не се възприемат до тогава, докато съответната команда не е
готова за фиксиране. Ако изпълняваната по предположение команда предизвиква
изключителна ситуация, последната предизвиква специфичен запис в буфера за
преподреждане. Ако се открие, че прогнозата за посоката на условния преход е
грешна и че командата не следва да се изпълнява, изключителната ситуация се потушава
заедно с командата, когато буферът за преподреждане се изчиства. Ако пък
командата достигне върха на буфера за преподреждане, то ние знаем, че тя повече
не е изпълняема по предположение (тя вече е станала безусловно изпълняема) и
изключителната ситуация трябва действително да се възприеме.
Изложената методика за изпълнение по предположение лесно може да се разпространи и върху целочислените регистри и функционалните устройства. Действително, спекулативното изпълнение на команди може да бъде полезно в целочислени програми, тъй като именно тези програми имат по-слабо предсказуемо поведение на преходите. Освен това, тези методи могат да бъдат разширени така, че да осигурят работа в процесори със зареждане на няколко команди в един такт. Спекулативното изпълнение вероятно е най-интересният метод именно за такива процесори, тъй като по-непретенциозните процесори могат да се задоволят и с паралелизма на ниво команди, изявяван само в базовите блокове и поддържан преди всичко от средствата на компилатор, който прилага технологията на разгъване на цикли.
Очевидно,
всички разгледани по-рано методи не могат да достигнат по-голяма степен на
разпаралелване, от заложената в конкретната приложна програма. Въпросът за
увеличаване степента на паралелизма в приложни системи в настоящо време
представлява предмет на интензивни изследвания, провеждани в цял свят.
Следващият раздел е:
5.3.8 Концепция EPIC –
явен паралелизъм на ниво команди