Последната актуализация на този раздел е от
2020 година.
5.3.2
Конвейерна организация на изпълнението на машинните команди
В предидущия
пункт кратко характеризирахме организационния принцип на съвместените операции.
Пояснихме, че в него се имат предвид две различни разбирания – за паралелизъм и
за конвейеризация. Освен това пояснихме, че подходът на разпределено управление
разцепва командния цикъл, опростява го и в същото време, въвеждайки
конвейерната организация на ниво машинни команди, при което обуславя
необходимостта от буферна памет за команди (вижте фигура
5.3.3). Тази необходимост, както значението, структурата и
функционирането на този вид памет са подробно дискутирани още в глава 6, §6.3 и пункт 6.3.1, на тази книга. Тук ще се
спрем върху същността на конвейерната организация на изчислителния процес на
ниво машинни команди и проблемите, които тя поражда.
За
да илюстрираме как този принцип се реализира в структурата на процесора от
фигура 5.1.3, ще приемем някои конкретни параметри за архитектурата му: ще
приемем например, че той съдържа 32 регистъра с общо предназначение (R0, R1, R2
,…, R31); още 32 регистъра за числа с плаваща запетая (FR0, FR1, FR2 ,…, FR31)
и брояч на командите ПБ. Ще считаме, че множеството изпълними за този процесор
операции включва типичните аритметически и логически операции, както и операции
с плаваща запетая. Ще считаме, че операндите за тези операции ще бъдат търсени
(адресирани) само в регистровата памет, а нейното обслужване (запис/четене) ще се
постига чрез операции за трансфер на данни. Ще приемем още съществуването на
операции за управление на прехода и някои системни операции. Ще считаме, че
операционното устройство е такова, че операциите в него се изпълняват за един
такт, т.е. функционирането му съответства на разбирането за RISK-процесори. При
това положение приемаме, че в командния цикъл последователно следват 4 етапа:
·
ДК – доставяне на командата по адреса, подаван от програмния брояч (от
паметта се прочита и доставя поредната машинна команда) ;
·
АО – декодиране (анализ) на командата / прочитане на операнди от регистровата
памет ;
·
ИО – изпълнение на операцията / изчисляване на действителен адрес в
оперативната памет ;
·
ФР – фиксиране на резултата и неговите признаци / обръщение към оперативната
памет.
Работата на конвейерите най-често се представя чрез особен вид времедиаграми, позволяващи да се проследят етапите на отделните команди в отделните тактове и тяхното взаимно разположение. Ще използваме тази техника за да представим и оценим изпълнението на един програмен участък при не конвейерно, т.е. последователно изпълнение на командите:
Номер на такта: |
Т1 Т2 Т3 Т4 |
Т5 Т6 Т7 Т8 |
Т9 Т10 Т11 Т12 |
Т13 Т14 Т15 Т16 |
Команда № r |
ДК АО ИО ФР |
|
|
|
Команда № r+1 |
|
ДК АО ИО ФР |
|
|
Команда № r+2 |
|
|
ДК АО ИО ФР |
|
Команда № r+3 |
|
|
|
ДК АО ИО ФР |
Фиг. 5.3.2.1. Времедиаграма
на последователно изпълнение на команди
Ще приемем, че продължителността на отделните последователни етапи е както следва: 50[ns], 50[ns], 60[ns], 50[ns]. Това е времето за което се превключват комбинационните схеми в отделните степени на конвейера. Както се вижда времето в третия такт е завишено с 10[ns]. Има се предвид различната сложност на алгоритмите за изпълнение на отделните операции. Към времето на отделните тактове следва да добавим и времето за запис на междинните резултати в тригерите на регистрите фиксатори в отделните степени на конвейера – примерно 5[ns]. Така общото време за изпълнение на 4 последователни команди при синхронен темп на управление, разпределено в 16 такта с продължителност 65[ns] всеки, ще бъде равно на 1040[ns].
Алтернативната организация на изчисленията е конвейерната. При 4-тактов цикъл за изпълнение на командите конвейерът ще има 4 степени, всяка от която ще се управлява от микрокода в съответния такт на микропрограмата на изпълняваната операция. Конвейерната структура е представена обобщено на следващата фигура. Вижда се, че микрокомандите на отделните машинни команди са разположени в опашките за всяка степен косо (с изоставане), т.е. според такта, в който ще управляват операционните устройства.
Фиг. 5.3.2.2. Структура на 4-степенен конвейер
Като приемем, че на всеки такт в конвейера се зарежда нова команда, схемата във времето би изглеждала по следния начин:
Номер на такта: |
Т1 |
Т2 |
Т3 |
Т4 |
Т5 |
Т6 |
Т7 |
Т8 |
Команда № r |
ДК |
АО |
ИО |
ФР |
|
|
|
|
Команда № r+1 |
|
ДК |
АО |
ИО |
ФР |
|
|
|
Команда № r+2 |
|
|
ДК |
АО |
ИО |
ФР |
|
|
Команда № r+3 |
|
|
|
ДК |
АО |
ИО |
ФР |
|
Фиг. 5.3.2.3. Времедиаграма на конвейерно изпълнение на команди
От схемата се вижда, че в четвърти такт първата команда завършва своето изпълнение с фиксиране на резултата и в същото време на входа на конвейера постъпва четвъртата по ред команда. Резултатът на последната ще бъде фиксиран в края на 7-ия такт. Така общата продължителност на изчислението от 4 последователни действия протича за 7 такта или общо за 455[ns]. Сравнението между двата вида организация може да се оцени с помощта на отношението 1040/455»2,3. Отношението на броя на тактовете между сравняваните организации: 16/7, има същата стойност и е известно още като коефициент CPI (clock cycles per instruction).Така за представения пример можем да твърдим, че конвейерният вид организация повишава производителността на процесора повече от 2 пъти, при същите по бързодействие логически схеми. Този резултат е толкова добър, че конвейерната организация не може да не бъде използвана в реалните процесори.
Конвейерът
и организацията на непрекъснато зареждане в него на последователни команди
обаче не е без проблеми. Съществуват редица реални последователности от
команди, за които тази организация се оказва неподходяща, тъй като опитвайки се
да я приложим, възникват ситуации, които се наричат конфликти.
В резултат конфликтите водят до нарушаване на тази организация и тогава
производителността се понижава. Съществуват три класа конфликти:
1.
Структурни конфликти. Възникват във връзка с апаратните ресурси на конвейера,
когато същите не поддържат всички възможни комбинации от команди желани за
зареждане в конвейера ;
2.
Конфликти по данни. Възникват в случаите, когато изпълнението на една
команда зависи от резултата, който получава предидущата команда ;
3.
Конфликти по управление. Възникват при конвейеризация на командите за управление
на прехода, чието изпълнение изменя съдържанието на програмния брояч.
Конфликтите
в конвейера предизвикват неговото спиране,
т.е. преустановява се зареждането и пробутване (изпълнението) на командите (pipeline
stall). Конфликтите изискват изменение в организацията на изчислителния
процес. Като цяло тя си остава конвейерна, но обогатена с действия, изпълняващи
се само в тези извънредни ситуации. Така например, ако дадена команда причини
спиране на конвейера, то всички следващи след нея команди също спират
изпълнението си. Ако е възможно, конвейерното изпълнение на следващите команди
може да продължи, но без зареждане на нови команди в конвейера. Така те
“изпреварват” спрялата команда, като я заобикалят.
Принципът за съвместено изпълнение на командите в общия случай изисква конвейеризация на функционалните (операционните) устройства и дублиране на ресурсите за разрешаване на всички възможни комбинации от команди в конвейера. Ако някаква комбинация от команди не може да бъде приета поради конфликт за ресурси, то говорим че в процесора има структурен конфликт. Най-типичен пример са процесорите с не напълно конвейеризирани функционални устройства. Причината се състои в това, че поради сложен алгоритъм или поради компромис с обема на апаратните разходи, конструкцията на такова устройство е реализирана въз основа на последователния микроалгоритъм, при което времето за неговото изпълнение се измерва с няколко синхро такта на тактовата последователност, синхронизираща работата на конвейера. В този случай, последователни команди, които използват това устройство, не могат да бъдат зареждани в него на всеки конвейерен такт.
Друга възможност за поява на структурни конфликти е свързана с недостатъчното дублиране на някои ресурси, което от своя страна пречи на изпълнението на произволна последователност от команди в конвейера и води до неговото спиране. Например, процесорът може да има само един порт за запис в регистровата памет, но при определени обстоятелства е възможно конвейерът да генерира и пожелае да изпълни два записа в един такт. Това е също структурен конфликт. Ясно е, че тази конструкция ще наложи спиране на конвейера, тъй като ще му се наложи да изчака освобождаването на изходния порт, тъй като ще бъдат изпълнени два последователни записа.
Структурни конфликти възникват още в процесори, които имат обща памет за данни и за команди. В този случай е възможен конфликт, когато една команда изисква обръщение към паметта за доставка на данни, когато по същото време от нея се извлича някоя следваща команда. Ситуацията може да се разреши със спиране на конвейера (pipeline stall) до завършване на завареното обръщение.
Описаните ситуации, в които възниква временен период на бездействие за конвейера, наричаме конвейерно мехурче (pipeline bubble). Това е метафора, с която изразяваме престоите във времето по хода на изчислителния процес. Вмъкване на мехурче или такова спиране на конвейера може да се постигне чрез прекратяване достъпа на тактовите импулси към фиксаторите във всички негови нива (вижте книга [2], фигури 8.4.2 и 8.4.3 или по-горе фигура 5.3.2.3).
При всички други обстоятелства, процесорът без структурни конфликти винаги ще се характеризира с изпълнение на командите за по-малък брой тактове. Естествено възниква въпросът защо конструкторите допускат наличието на структурни конфликти? За това могат да се изтъкнат две причини:
· Стремеж към понижаване на цената и ;
· Намаляване на закъсненията в устройствата.
Конвейеризацията на всички функционални (операционни) устройства може да се окаже много скъпа. Процесори, които допускат например две обръщения към паметта в един такт, трябва да имат памет с удвоена пропускателна способност. Обикновено това се постига с прилагане на така наречената Харвардска архитектура – разделни буферни памети за команди и за данни или с двупортова памет. Аналогично например е твърдението за напълно конвейеризирано устройство за деление на числа с плаваща запетая (вижте фигура 3.8.3.8). В този случай на реализация се изисква огромно количество градивни логически елементи. Ако структурните конфликти не възникват много често, то може би не си струва да се плаща така скъпо за това те да бъдат преодолявани. Като правило, може да бъде разработено неконвейерно, или не напълно конвейерно функционално устройство, което да има общо закъснение по-малко от това на напълно конвейерното. Естествено използването на такова устройство в отделна степен на конвейера изисква понижаване на темпа за управлението на последния. Такъв пример представляват някои реални устройства с плаваща запетая в процесори на CDC или MIPS например, в които вместо пълна конвейеризация е предпочетено апаратно-схема реализация.
Един
от факторите, който оказва съществено влияние на производителността на конвейерните
системи, представляват логическите зависимости между командите. Тези
зависимости в голяма степен ограничават потенциалния паралелизъм в съседни
операции. Степента на влияние на тези зависимости се определя от
характеристиките на програмата, а така също от архитектурата на процесора (от
структурата за управление на командния конвейер и от параметрите на
функционалните устройства). Конфликтите по данни възникват в случите, когато
конвейерната обработка променя реда за обръщение към операндите, в
сравнение с последователната обработка.
|
Т1 |
Т2 |
Т3 |
Т4 |
Т5 |
Т6 |
Т7 |
Т8 |
ADD R1,R2,R3 |
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
Read |
|
Write |
|
|
|
|
SUB R4,R1,R5 |
|
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
Read |
|
Write |
|
|
|
AND R6,R1,R7 |
|
|
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
Read |
|
Write |
|
|
OR R8,R1,R9 |
|
|
|
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
Read |
|
Write |
|
XOR R10,R1,R11 |
|
|
|
|
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
Read |
|
Write |
Фиг. 5.3.2.4. Илюстрация на
конфликт по данни
В представената схема е записана последователност от 5 команди, указващи на действията събиране, изваждане, логическо И, логическо ИЛИ и логическа неравнозначност. Прието е изпълнението на операциите да се разбира според следните означения:
R1 := (R2) + (R3)
- сумата от съдържанията на
регистър R2 и R3 се записва в регистър R1 ;
R4 := (R1) - (R5)
- разликата от съдържанията на R1
и R5 се записва в R4 ;
R6 := (R1) Ç (R7) - поразрядната конюнкция от съдържанията на R1 и R7 се
записва в R6;
R8 := (R1) È (R9) - поразрядната дезюнкция от съдържанията на R1 и R9 се
записва в R8;
R10 := (R1) Å (R11) - поразрядната сума от съдържанията на R1 и R11 се записва
в R10.
Това
което се вижда е, че получената след първата операция сума, се използва като
първи операнд във всички следващи операции. Команда ADD записва своя
резултат в регистър R1,
а команда SUB чете съдържанието на този регистър като първи операнд. За
съжаление, както може да се види в конвейерната схема по-горе, прочитането на
регистър R1 от тази команда се реализира преди предидущата команда да е
записала актуалния резултат! Аналогично е положението и със следващата команда AND.
Ако не се вземат мерки за предотвратяване на този конфликт, командата SUB ще
прочете и използва неправилна стойност. В същност стойността, която ще
използва команда SUB, е неопределена – въпреки, че можем да предположим, че в
регистър R1 би се съхранявала някаква стойност получена от команда, предхождаща
команда ADD, това не винаги е така. Ако например възникне прекъсване
между командите ADD и SUB, то команда ADD ще завърши
своето изпълнение напълно и в регистър R1 ще се запише нейният резултат.
Тогава, след връщане от прекъсване команда SUB ще използва правилна
стойност. Да се разчита обаче на подобно непрогнозирано поведение в системата е
неприемливо.
Проблемът, който се поставя в този пример, може да бъде разрешен с помощта на достатъчно проста апаратна техника, която се нарича транзитно прехвърляне на данни (data forwarding), или заобикаляне, обхождане (data bypassing), или още окъсяване (short-circuiting). Както се вижда наименованията са няколко, но същността е една – резултатът от изпълнението на дадена операция, който се получава в изходния регистър на АЛУ, винаги се подава назад отново на неговия вход. Ако апаратурата открие, че предидущата операция на АЛУ записва резултат в регистър, който съответства на източника на операнда за следващата операция на АЛУ, то логическите схеми за управление избират в качеството на вход за АЛУ резултатът, който постъпва по веригата за заобикаляне, а не стойността, която е прочетена от регистровата памет. Изказаното правило представлява техниката за заобикаляне и се илюстрира със структурата, представена на следващата фигура 5.3.2.5. Тази техника може да бъде обобщена и резултатът да се изпраща за запис (фиксиране) направо в онова функционално устройство, което се нуждае от него. Така резултатът от изхода на едно устройство се “препраща” на входа на друго устройство.
Фиг. 5.3.2.5. Конвейерна структура със “заобикалящи” (транзитни) връзки
В1) Класификация на конфликтите по данни
Конфликт възниква на всяко място в програмата, където има зависимост между командите, които като са записани достатъчно близко една спрямо друга, съвместяването на операциите се осъществява фактически при тяхната конвейеризация. Както вече показахме по-горе (вижте фигура 5.3.2.4), при такъв конфликт е възможно да се измени реда за обръщение към операндите. За разлика от този пример, в който конфликтът става с регистрови операнди, конфликт е възможен още поради зависимост на двойка команди, които изпълняват операции четене или запис в една и съща клетка на оперативната памет. Ако обаче при реализация на достъпа до паметта заявените обръщения се изпълняват строго в реда, в който са възникнали, то появата на такъв тип конфликти ще бъде предотвратена.
Известни са три възможни конфликта по данни в зависимост от реда на операциите четене и запис. Ще разгледаме две команди – команда №q и команда №k, при това ще приемем, че команда №q предхожда команда №k (в текста на програмата). Възможни са следните конфликти:
· RAW (read after write) – четене след запис. При своето изпълнение команда №k се опитва да прочете операнд от източник на данни, преди предхождащата я команда №q да е записала там актуалния резултат. По този начин команда №k може да получи некоректна стара стойност. Този вид конфликти е най-често срещания, а тяхното преодоляване се реализира чрез механизма на транзитните връзки, който разгледахме вече.
· WAR (write after read) – запис след четене. Команда №k се опитва да запише резултат в приемник на операнд преди неговото съдържание да е прочетено от команда №q. Така вместо необходимата стойност, команда №q ще работи с актуализираното съдържание и ще получи некоректен резултат. Такива конфликти могат да възникнат в системи, които допускат изпълнение на команди не в реда, в който те са разположени в текста на програмата. В същото време, в системи с централизирано управление на потока от команди, такива конфликти като правило не настъпват, тъй като те осигуряват правилния ред на изпълнение на командите.
· WAW (write after write) – запис след запис. Команда №k се опитва да запише операнд в приемник на данни, преди в същия да е записала резултата си команда №q. По този начин записите в приемника за данни се извършват в неправилен ред, при което в него остава записана неподходящата стойност. Този вид конфликти е възможен само в конвейери, записи от които могат да се извършват от много нива, или позволяват изпълнението на дадена команда да продължава дори в случая, когато изпълнението на предидущата е спряно.
В2) Конфликти по данни, водещи до спиране на
конвейера
За съжаление не всички потенциални конфликти по данни могат да се разрешават чрез механизъма на транзитните връзки. Ще разгледаме следната последователност от команди:
Команда |
Коментар |
LOAD R1, 32(R6) |
R1 := (Mem[(R6)+32]),
зареждане в регистър R1 на съдържанието на клетка от паметта, относително
адресирана спрямо базовия адрес в регистър R6 и отместване D=32. |
ADD R4, R1, R7 |
R4 := (R1)+(R7),
сумата от съдържанията на R1 и R7 се записва в R4 |
SUB R5, R1,R 8 |
R5 := (R1)+(R8),
разликата от съдържанията на R1 и R8 се записва в R5 |
AND R6, R1, R7 |
R6 := (R1)Ç(R7),
конюнкцията от съдържанията на R1 и R7 се записва в R6 |
Ако приемем,
че команда LOAD чете операнда си от регистър R6 във втори такт (АО) и го
записва в регистър R1 в четвъртия такт (ФР), то следва, че следващите 2 команди
ще имат конфликт по данни, тъй като при тяхното конвейерно изпълнение,
съдържанието на регистър R1 няма да бъде правилното. Конфликтът може да бъде
отстранен чрез спиране на конвейерното изпълнение на следващите команди до
момента, когато стане възможно използването на необходимата стойност.
|
Т1 |
Т2 |
Т3 |
Т4 |
Т5 |
Т6 |
Т7 |
Т8 |
T9 |
LOAD R1, R6 |
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
|
Read |
|
Write |
|
|
|
|
|
ADD R4,R1,R7 |
|
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
|
Read |
|
Write |
|
|
|
|
SUB R5,R1,R8 |
|
|
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
|
Read |
|
Write |
|
|
|
AND R6,R1,R7 |
|
|
|
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
|
Read |
|
Write |
|
|
|
|
|
|
|
|
|
|
|
|
LOAD R1, R6 |
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
ADD R4,R1,R7 |
|
ДК |
АО |
stall |
stall |
ИО |
ФР |
|
|
SUB R5,R1,R8 |
|
|
ДК |
stall |
stall |
АО |
ИО |
ФР |
|
AND R6,R1,R7 |
|
|
|
stall |
stall |
ДК |
АО |
ИО |
ФР |
Фиг. 5.3.2.6. Последователност
от команди със спиране на конвейера
В горната част на представената времедиаграма са изобразени конфликтните тактове. В долната част е показано двутактовото задържане на конвейерното изпълнение на потока команди, в резултат на което конфликтите са отстранени и командите ще получат правилни резултати. Логиката на задържането се състои в това, че етапът на формиране на адреса на операнда и неговото прочитане (АО) да се получи винаги след етапа за фиксиране на резултата (ФР).
Решение за спиране на конвейера взема специална апаратна схема, която следи и открива този вид конфликти. Апаратурата за вътрешна блокировка на конвейера (pipeline interlock) осигурява коректното изпълнение на този вид конфликти. Апаратурата спира конвейера за последователността от команди, започвайки от командата, която иска да използва данните в онзи момент, когато предидущата команда, е в процес на тяхното създаване. Така се появява мехурче в конвейерния процес, точно така както в случая на структурни конфликти.
В3) Планиране по време на компилиране
отстраняването на конфликти по данни
Много от видовете спирания на конвейера могат да се случват достатъчно често. Например, за реализация на оператора за присвояване A=B+C, един компилатор най-вероятно би генерирал следващата последователност от машинни команди:
LOAD R1, B R1:=(MemB) ;
LOAD R2, C R2:=(MemC) ;
ADD R3, R1, R2 R3:=(R1)+(R2) ;
STORE A, R3 MemA:=(R3) .
Конвейерното изпълнение на този линеен програмен участък е изразено чрез следващата времедиаграма.
|
Т1 |
Т2 |
Т3 |
Т4 |
Т5 |
Т6 |
Т7 |
Т8 |
T9 |
T10 |
T11 |
LOAD R1, B |
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
|
|
|
|
|
R1=B |
|
|
|
|
|
|
|
LOAD R2, C |
|
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
|
|
|
|
|
R2=C |
|
|
|
|
|
|
ADD R3,R1,R2 |
|
|
ДК |
stall |
stall |
АО |
ИО |
ФР |
|
|
|
|
|
|
|
|
|
Read R1,R2 |
|
R3=S |
|
|
|
STORE A, R3 |
|
|
|
|
|
stall |
stall |
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
|
|
|
Read R3 |
|
|
Фиг. 5.3.2.7. Конвейерно изчисление на израза A=B+C
Очевидно е, че изпълнението на команда ADD следва да бъде преустановено дотогава, докато не стане достъпен в регистър R2 от СОЗУ и операндът C. Същото закъснение трябва да се наложи и на следващата команда за запис, която трябва да изчака фиксирането на сумата S=B+C в регистър R3.
За този елементарен пример компилаторът няма да може да облекчи ситуацията, но в редица по-общи случаи той е в състояние да реорганизира последователността от команди така, че да се избегне спирането на конвейера. Тази техника, наричана планиране на зареждането на конвейера (pipeline scheduling) или още планиране на потока команди (instruction scheduling), е използвана още в началото на 60-те години на миналия век, но тя се практикува и усъвършенства масово едва в 80-те години.
Ще разгледаме класически пример, който читателят може да намери в много литературни източници. Въпросът е, как да се проведат изчисленията за следните два оператора за присвояване:
A = B+C ; D = E-F ;
Вижда се, че между двата математически израза няма връзка. Ще приемем още, че операндите A,B,C и D, се намират в оперативната памет и тяхното зареждане в регистър на СОЗУ отнема един такт. За всеки операнд е определен отделен регистър. Необходимо е да се състави такъв машинен код за тези изчисления, при който няма да настъпи спиране на конвейера. Нека разгледаме следната естествена последователност:
Команда |
Коментар |
LOAD RB, B |
|
LOAD RC, C |
|
ADD RA, RB, RC |
Блокировка за 2 такта, поради липса на операнд |
STORE A, RA |
Блокировка за 2 такта, поради липса на операнд |
LOAD RE, E |
|
LOAD RF, F |
|
SUB RD, RE, RF |
Блокировка за 2 такта, поради липса на операнд |
STORE D, RD |
Блокировка за 2 такта, поради липса на операнд |
Спирането на
конвейера на два пъти за по 2 такта е необходимо за изчакване завършването на
командите за зареждане на вторите операнди, съответно C и F. Ситуацията е
напълно аналогична на показаната по-горе на фигура 5.3.2.7. Така всяка група от
по 4 команди внася закъснение от 4 такта и вместо 11 изчислението изисква 19 такта.
Ще приложим логиката на разместването на командите така щото да бъде отстранена или поне намалена тяхната взаимна зависимост. Ако това е възможно, минимизирането на времето за изчисляване е гарантирано. Въз основа на тази логика е извършено преподреждането на командите от горния текст и на долната времедиаграма е изразен изчислителния процес при новия текст:
|
Т1 |
Т2 |
Т3 |
Т4 |
Т5 |
Т6 |
Т7 |
Т8 |
T9 |
T10 |
T11 |
T12 |
T13 |
LOAD RB, B |
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
|
|
|
LOAD RC, C |
|
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
|
|
LOAD RE, E |
|
|
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
|
LOAD RF, F |
|
|
|
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
ADD RA, RB, RC |
|
|
|
|
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
SUB RD, RE, RF |
|
|
|
|
|
ДК |
stall |
АО |
ИО |
ФР |
|
|
|
STORE A, RA |
|
|
|
|
|
|
stall |
ДК |
АО |
ИО |
ФР |
|
|
STORE D, RD |
|
|
|
|
|
|
stall |
stall |
stall |
ДК |
АО |
ИО |
ФР |
Фиг. 5.3.2.8. Пример за
оптимизиране на конфликтите от компилатора
Както се
вижда, пълно отстраняване на зависимостите в този пример не е постигнато, но
оптималността на новия текст е безспорна. Команда SUB трябва да изчака
записа на операнд F в регистър RF , а втората команда STORE трябва да изчака записа
на разликата (E-F) в регистър RD. Така закъснението в това изчисление е само 2 такта.
Следва
да отбележим, че използването на 2 различни регистъра за фиксиране на сумата и
разликата, позволява свободното разположение на командите STORE в
текста, т.е. във времето и способства за по-доброто планиране на изчислителния
процес от компилатора. В частност, ако се вземе решение разликата да бъде
фиксирана също в регистър RA , то преди това е задължително употребата на команда STORE,
която ще го освободи, записвайки сумата в паметта. Такова обвързване на
командите във фиксиран ред обаче прави логиката на преподреждането невъзможна.
От тук следва изводът, че планирането на потока команди в конвейера изисква
увеличаване на обема на регистровата памет на процесора. Увеличаване броя на
регистрите с общо предназначение може да се окаже съществено за архитектури,
които зареждат за изпълнение няколко команди в един такт.
Съвременните
компилатори прилагат техниката pipeline scheduling за повишаване
на производителността на конвейера. В тривиалните алгоритми компилаторът просто
планира разпределението на командите в един базов блок (линеен програмен
участък, в който не се съдържат команди за управление на прехода, за изключение
в началото и в края на този участък). Планирането на такава последователност се
осъществява достатъчно лесно, тъй компилаторът “знае”, че всяка команда в блока
се изпълнява, ако се изпълни първата. И така, може просто да се построи граф
(таблица) на зависимостите между командите в участъка и след това същите да
бъдат преподредени с цел да се отстранят или минимизират зависимостите и да се
минимизират конвейерните мехурчета. За прости конвейери тази стратегия е
напълно удовлетворителна. За по-наситени и интензивни конвейери обаче се налага
да се използва значително по-сложни алгоритми за планиране.
За
щастие съществуват методи, чиято апаратна реализация позволява да се промени реда
за изпълнение на командите така, че спиранията на конвейера се минимизират.
Тези методи са получили общото наименование динамична
оптимизация. Основните средства на динамичната оптимизация са :
1.
Разполагане на схемите за
откриване на конфликти в началните нива на конвейера, което позволява на
командата да се придвижва в конвейера до момента, когато реално ще й потрябва
операнд, представляващ резултат на по-предна незавършила изпълнението си
команда. Алтернативен подход представляват схемите за централизирано откриване
на конфликтите още в началните нива на конвейера ;
2.
Буферизация на командите,
очакващи разрешаване на техния конфликт и пробутване (изпълнение) на следващите
логически несвързани команди, които “заобикалят”, минават транзитно покрай
буфера. В този случай командите ще бъдат подавани за изпълнение не в този ред,
в който са подредени в текста на програмата. Апаратурата за управление на
конвейера обаче е длъжна да осигури коректни резултати в съответствие с
алгоритъма на програмата ;
3.
Съответна организация за
комутиране на магистралите (шините и връзките), осигуряваща внасяне на
резултата (междинния) от операцията непосредствено в онзи буфер, който
съхранява логически зависимата команда, задържана по причина на конфликта, или
непосредствено на вход на функционалното устройство до момента, когато този
резултат бъде записан в регистровата памет или в оперативната памет. Последното
се постига чрез така наречените транзитни връзки, подход, който вече
разгледахме.
Друг апаратен
метод за минимизация на конфликтите по данни представлява методът за преименуване на регистрите (register renaming).
Този метод е получил своето име от широко прилагания в компилаторите метод за
преименуване В компилаторите се прилага метод за такова разпределение на
данните, което цели минимизиране на зависимостите при отразяване на обектите в
изходната програма (променливите) върху апаратните ресурси на процесора (клетки
в оперативната памет и регистри с общо предназначение).
При
апаратната реализация на метода за преименуване на регистрите се отделят логически регистри, обръщението към които се
изпълнява с помощта на съответните адресни полета в командата, а така също и физически регистри, които реално съществуват в
СОЗУ на процесора. Номерата (адресите) на логическите регистри динамически
отразяват номерата на физическите регистри. Съответствието се постига с помощта
на таблици на съответствието, които се актуализират след декодирането на всяка
команда. Всеки нов резултат се записва в нов физически регистър. Обаче
предидущото значение на всеки логически регистър се съхранява и може да бъде
възстановено, ако изпълнението на командата трябва да бъде прекъснато поради
изключителни събития или при неправилно предсказан условен адресен
(алгоритмичен) преход.
При
изпълнение на програмата се генерират множество временни регистрови резултати.
Тези временни стойности се записват в регистровия файл заедно с постоянните
стойности. Една временна стойност става нова постоянна стойност, когато завърши
изпълнението на командата и се фиксира нейния резултат. На свой ред
изпълнението на командата завършва, когато всички предидущи команди успешно
завършат изпълнението си според реда си в текста на програмата.
Програмистът
работи само с логическите регистри. Реализацията на физическите регистри е скрита
от него. Както вече отбелязахме, номерата на логическите регистри се поставят в
съответствие на номерата на физическите регистри. Таблиците на съответствието
се актуализират след декодирането на всяка команда. Всеки нов резултат се
записва във физически регистър. Докато не завърши изпълнението на съответната
команда обаче, стойността във физическия регистър се счита за временна.
Методът
за преименуване на регистрите опростява контрола върху зависимостите по данни.
В процесори, които могат да изпълняват командите в ред различен от реда им в
текста на програмата, номерата на логическите регистри могат да станат двусмислени,
тъй като един и същи регистър може да бъде избиран последователно за съхранение
на различни стойности. Но тъй като номерата на физическите регистри са
уникални, те идентифицират еднозначно всеки резултат, с което нееднозначността
се отстранява.
Конфликтите
по управление могат да предизвикат много по-големи загуби в производителността
на конвейера по сравнение с конфликтите по данни. Когато се изпълнява команда
за условен преход, в зависимост от логическата стойност на проверяваното
условие, тя може да промени или да не промени съдържанието на програмния брояч.
Говорим, че преходът се изпълнява, ако командата зарежда адреса
за преход в програмния брояч и говорим, че не се изпълнява в противен
случай.
Тук
искаме да предупредим читателя, че командите за управление на прехода създават
проблеми още в процеса на тяхното буфериране в кеш-паметта за команди, което налага
техния предварителен анализ по време на изпреварващото им извличане от
оперативната памет. В същност там е казано, че командите за безусловен преход
се изпълняват още в процеса на предварителния анализ и не се буферират.
Последното означава, че те изобщо не достигат до конвейера. Искаме да уведомим
читателя, че тези именно проблеми, са пояснени в глава
6, §6.3 на тази книга.
Известно
е, че най-тривиалният метод за обработка на командата за условен преход (ако тя
въобще попадне в конвейера) се изразява в спиране на придвижването на
следващите я команди в момента, когато при нейното декодиране се разбере, че тя
е такава, до момента, в който тя завършва записа на новия адрес в програмния
брояч. Казаното може да се илюстрира със следната времедиаграма:
|
|
Т1 |
Т2 |
Т3 |
Т4 |
Т5 |
Т6 |
Т7 |
Т8 |
T9 |
T10 |
T11 |
T12 |
Условен преход
a |
|
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
|
|
Следваща команда
+1 |
|
|
ДК |
stall |
stall |
ДК |
АО |
ИО |
ФР |
|
|
|
|
Следваща команда
+2 |
|
|
|
stall |
stall |
stall |
ДК |
АО |
ИО |
ФР |
|
|
|
Следваща команда
+3 |
|
|
|
stall |
stall |
stall |
stall |
ДК |
АО |
ИО |
ФР |
|
|
Следваща команда
+4 |
|
|
|
stall |
stall |
stall |
stall |
stall |
ДК |
АО |
ИО |
ФР |
|
Следваща команда
+5 |
|
|
|
stall |
stall |
stall |
stall |
stall |
stall |
ДК |
АО |
ИО |
ФР |
Фиг. 5.3.2.9. Спиране на
конвейера при зареждане на команда за условен преход
Както се вижда в такт Т2 се зарежда следващата команда, но в този такт става ясно, че декодираната в предидущия такт команда е команда за условен преход. В резултат на този факт апаратурата за управление на конвейера взема решение за спиране на зареждането и изпълнението на следващите команди, докато в такт Т4 командата за условен преход не запише в програмния брояч новия адрес a. Едва след това, в такт Т5 започва извличането и изпълнението на следващите команди в конвейера. Така излиза, че изпълнението на командите след условния преход започва на чисто, или със закъснение от 3 такта. Започналото в такт Т2 зареждане на следващата команда се изоставя – актуална се оказва командата, заредена в такт Т5, възможно по адрес a, ако условието за преход е било изпълнено.
Ако спирането на конвейера е за 3 последователни такта при всяка команда за условен преход, то това може да се отрази крайно негативно върху производителността на процесора. Като се има предвид, че командите за условен преход в една програма са около 30% от целия й текст, то конвейерният процесор губи почти половината от производителността си! Така минимизирането на тези загуби се превръща в критически въпрос.
Броят на тактовете, които се губят при условни преходи поради спиране на конвейера за следващите команди, е възможно да бъде намален по два начина:
1.
Чрез ранна проверка на условието
за преход. Под “ранна” разбираме началните степени на конвейера ;
2.
Чрез ранно определяне на адреса
за преход в програмния брояч.
В някои процесори конфликтите по причина на условните преходи причиняват големи загуби на тактове, много повече от показаните в дадения пример, тъй като времето за проверка на условието за преход и изчисление на адреса за преход според съответния метод за адресиране отнема значителен брой тактове. Например, в процесор с отделни степени за извличане и за декодиране на командата е възможно да се появи закъснение на условния преход (продължителност на конфликта по управление), което е най-малко на един такт по-дълго. Закъснението в процесори с дълбоки конвейери имат закъснение на условните преходи от 4 до 7 такта. В общият случай, колкото по-голяма е дълбочината на конвейера, толкова по-големи са закъсненията от команди за условен преход, изчислявани в съответния брой тактове. В същото време ефектът от намаляване на относителната производителност зависи коефициента CPI на процесора. Процесори е високи стойности на CPI могат да имат условни преходи с по-голямо закъснение, тъй като загубената процентна производителност по тяхна причина е относително по-малка.
Има няколко метода за минимизиране на спиранията на конвейера по причина на команди за условни преходи. Тук ще бъдат обсъдени кратко 4 тривиални схеми (алгоритмични), които се прилагат при компилиране на програмите. Някои от тях се прилагат при всички видове команди за преход. В тези схеми предсказването на условните преходи е статично. Читателят може да намери допълнителни обяснения, свързани със статичното и динамично предсказване на преходите, в глава 6, пункт 6.3.1 на тази книга. Същността на статичното предсказване се състои в това, че прогнозата на посоката на условните преходи се фиксират за всяка команда за условен преход за през цялото време на изпълнение на програмата, колкото и пъти програмата да преминава през този условен преход.
1.
Метод на изчакването. Най-простата схема за обработка на командата за условен
преход представлява преустановяване на зареждането на конвейера с команди,
непосредствено следващи командата за условен преход, докато не стане известна
посоката на прехода. Именно тази схема е изразена по-горе на фигура 5.3.2.9 ;
2.
Метод на продължението. По-добра и не толкова сложна е схемата, при която се
приема, че конвейерът продължава да се зарежда с команди, които непосредствено
следват командата за условен преход. В същност това най-често е посоката на
неизпълненото условие (клон “лъжа”). В този случай следва да се вземат мерки да
не се променя състоянието на машината, докато не стане известно действителната
посока на прехода. Ако действителният преход се окаже в посока “истина”, то
конвейерът се изчиства и започва зареждане на команди от клона “истина”.
Конвейерът видимо не е спирал в този случай, но извършените изчисления в него
се оказва, че трябва да бъдат изоставени като непотребни. От момента на
зареждане на нова команда от правилия клон, до получаване на нейния резултат
обаче ще се получи “конвейерно мехурче” с продължителност равна на броя на
степените на конвейера. Изчистването на конвейера от напразно заредените
команди, в случай на неправилно прогнозиран преход, не е задължително –
достатъчно е да бъде забранено фиксирането на получените от тях резултати. Това
е възможно, тъй като стойността на проверяваното условие за преход е вече
известно в такт Т2.
|
|
Т1 |
Т2 |
Т3 |
Т4 |
Т5 |
Т6 |
Т7 |
Т8 |
T9 |
T10 |
T11 |
b: Условен преход a |
|
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
|
|
Следваща команда
b+1 |
|
|
ДК |
АО |
ИО |
|
|
|
|
|
|
|
Следваща команда
b+2 |
|
|
|
ДК |
АО |
|
|
|
|
|
|
|
Следваща команда
b+3 |
|
|
|
|
ДК |
|
|
|
|
|
|
|
¾ ¾ ¾ ¾ ¾ ¾ ¾ |
|
¾ |
¾ |
¾ |
¾ |
¾ |
¾ |
¾ |
¾ |
¾ |
¾ |
¾ |
¾ ¾ ¾ ¾ ¾ ¾ ¾ |
|
¾ |
¾ |
¾ |
¾ |
¾ |
¾ |
¾ |
¾ |
¾ |
¾ |
¾ |
Следваща команда
a |
|
|
|
|
|
ДК |
АО |
ИО |
ФР |
|
|
|
Следваща команда
a+1 |
|
|
|
|
|
|
ДК |
АО |
ИО |
ФР |
|
|
Следваща команда
a+2 |
|
|
|
|
|
|
|
ДК |
АО |
ИО |
ФР |
|
Следваща команда
a+3 |
|
|
|
|
|
|
|
|
ДК |
АО |
ИО |
ФР |
Фиг.
5.3.2.10. Обработка
на команда за УП според метода на продължението
в случая на неправилно прогнозиран преход “лъжа”
Както се вижда от горната фигура, след командата за условен преход, конвейерът се зарежда с команди от следващите адреси (b+1), (b+2), (b+3), а това са адреси в клона “лъжа” на условния преход. В такт Т2 става ясно, че този клон е бил неправилно предположен и след зареждане на програмния брояч с новия адрес (адресът за преход) в такт Т4, междинните резултати на погрешно заредените команди се изтриват. Защрихованите полета в горната времедиаграма съответстват на етапите изчистените команди. Изпълнението на командата от клетка (b+1) е стигнало до етап ИО (изпълнение на операцията), а на следващите две – до етапи АО (адреси на операнди) и ДК (доставка на команда) съответно. В тактовете Т5, Т6 и Т7 резултати не се фиксират. В същото време в такт Т5 започва изпълнението на първата команда от адрес (a+1), т.е. от правилния клон, която фиксира резултат в такт Т8. Пропуснатите тактове в този пример са 3.
3.
Съществува алтернативна схема,
която приема да предполага изход винаги по клона “истина”, т.е. приема
преходите винаги изпълняеми. При тази предпоставка след командата за
условен преход се зареждат команди от колона на изхода “истина”. Това разбира
се възможно, ако адресът за преход е изчислен предварително, в резултат на
което са били буферирани команди от така предположения клон на условния преход.
Ако това не е възможно, не остава нищо друго освен да се изчака оценката на
истинската стойност на условието за преход и съответния адрес за преход, който
да бъде зареден в програмния брояч. В последния случай процесът прилича на
този, който изобразихме по-горе на фигура 5.3.2.10.
4.
И на края, четвъртата схема се
нарича схема на задържаните преходи. В тази схема се реализира задържан
на n такта преход,
който се осмисля с помощта на следната рисунка:
Казваме за
командите от 1 до n, че се намират в слотове на задържан преход (във
временни интервали на задържания преход) (branch-delay slot), т.е. след
командата за преход има n на брой слота (гнезда, места). Оптимизацията на
подобен програмния код чрез подходящи правила за компилиране цели да
натовари равномерно и без прекъсвания конвейера. Това се постига чрез
съответно преподреждане на командите и чрез вмъкване в подходящите места на
команди NOOP (няма операция или още празна команда), така щото командите за
преход да не причиняват спиране на конвейера.
На
следващата фигура 5.3.2.11 са изобразени три програмни текста, при които
компилаторът може да планира задържан преход. Горната част на рисунката
представя първоначалната последователност от машинни команди, а в долната част
– последователността, която е получена в резултат на планирането.
Фиг.
5.3.2.11. Планиране на задържан преход с цел оптимизация на конвейерното
изпълнение
В случай а) от горната рисунка слотът за задръжка се запълва с независима команда, намираща се преди командата за условен преход. Това е най-добрият избор. Другите две схеми б) и в) се прилагат в случаите когато е невъзможно прилагането на схемата по правило а).
В
последователностите от команди в случаите б) и в) използването на съдържанието
на регистър R1 в качеството му на условие за преход възпрепятства преместването
на команда ADD (която записва резултат в същия регистър R1) след
командата за преход. В случай б) слотът на задържане се запълва с командата,
която се намира в целевия адрес за преход на командата за преход. Обикновено се
налага тази команда да бъде копирана, тъй като към нея са възможни обръщения и
от други части на програмата. На схемата б) се отдава предпочитание, когато с
висока вероятност се предполага преходът да е изпълняем, например ако този
преход е преход към входната точка на цикъл.
И
накрая, слотът на задръжка може да се запълни с команда, която се намира между
командата по неизпълняемия преход и командата по целевия адрес на прехода,
какъвто е случаят в). За да бъде подобна оптимизация “законна”, то изпълнението
на команда SUB би следвало да бъде възможно ако преходът не се насочи в
прогнозираната посока. При това се предполага, че команда SUB ще изпълни
ненужно изчисление, но като цяло програмата ще бъде изпълнена коректно. Това ще
бъде така, ако например регистър R4 бъде използван само за временно съхранение
на междинни резултати, когато преходът се изпълнява в непрогнозната посока.
В
следващата таблица по-долу са изразени ограниченията за споменатите три схеми
за планиране на условните преходи и ситуациите, когато това води до положителен
резултат. Компилаторът следва да спазва тези изисквания при подбор на
подходящата команда, с която запълва слота на задръжка. Ако такава команда не
бъде намерена, слотът се запълва с празна команда NOOP.
Таблица 5.3.2.1 Ограничения в схемите за планиране
Схема |
Изисквания |
Кога се получава увеличена
производителност |
а) |
Командата за условен преход не трябва да зависи от
преместваната команда |
Винаги |
б) |
Изпълнението на преместената команда трябва да бъде
коректно, даже ако преходът не бъде изпълняван. Възможно е да се наложи
копиране на командата. |
Когато преходът се изпълнява. Обемът на програмата се
увеличава поради копирането на тези команди. |
в) |
Изпълнението на преместената команда трябва да бъде
коректно, даже ако преходът бъде изпълняван. |
Когато преходът не се изпълнява. |
Планирането на
задържаните преходи се усложнява
1.
От наличието на ограничения
върху командите, чието разполагане се планира в слотовете на задръжка ;
2.
От необходимостта да се
предсказва по време на компилиране ще бъде ли условния преход изпълняем или не.
Можество статистически експерименти показват, че ефективността на планирането на преходите с един слот на задръжка (възможно най-елементарната схема) е висока – повече от 60% от слотовете се запълват успешно. При това повече от 80% от така запълнените слотове се оказват полезни за изпълнението на програмите. Това може да ни учуди, тъй като условните преходи се оказват изпълнени примерно на около 53% от случаите. Високият процент оползотворени слотове се обяснява с това, че почти половината от тях се оказват запълнени с команди, които предхождат командите за условен преход, т.е. по схема а), изпълнението на които е необходимо независимо от това изпълнява ли се преходът, или не.
Съществуват известни неголеми допълнителни апаратни разходи за реализация на задържаните преходи. Поради ефекта на задържаните условни преходи, за коректно възстановяване на състоянието на процесора в случай на прекъсване, са необходими няколко програмни брояча (един плюс дължината на задържането).
При статическото прогнозиране (предсказване) на преходите се използват два метода:
1. Метод, при който се изследва структурата на програмата. Изследването на структурата на програмата е достатъчно просто. Първоначално в изходната точка може да се предположи, че всички преходи назад в програмата са изпълняеми, преходите напред по програмата – неизпълняеми. Основавайки се на това предположение прогнозирането на преходите за повечето програми води до ниска ефективност, което означава, че структурата на програмата не е най-информативният признак, по който може да се направи добра прогноза ;
2. Метод, при който се използва информация за профила на изпълнението на програмата, събрана в резултат на предварителни изпълнения на програмата. Това, което прави този подход по-успешен, е фактът, че поведението на преходите при изпълнение на програмата често се повтаря. Всеки отделен преход в програмата често се оказва отместване в една и съща посока, т.е. той е или изпълняем или неизпълняем. Това становище се споделя от много автори на различни публикации.
Тъй като схемите за динамическо прогнозиране на преходите се основават в голяма степен на изложените по-горе идеи и подходи, същите се оказват съществени.
Устройство
|
Задръжка
|
Скорост на
повторение
|
Целочислено АЛУ
|
1
|
1
|
Събиране с плаваща
запетая
|
4
|
2
|
Умножение (с ФЗ и
с ПЗ)
|
6
|
3
|
Деление (с ФЗ и с
ПЗ)
|
15
|
15
|
|
|
Т1 |
Т2 |
Т3 |
Т4 |
Т5 |
Т6 |
Т7 |
Т8 |
T9 |
T10 |
MULTF F0, F4, F6 |
|
ДК |
АО |
ИО11 |
ИО12 |
ИО13 |
ИО21 |
ИО22 |
ИО23 |
ФР |
|
. . . . . . |
|
|
ДК |
АО |
ИО |
ФР |
|
|
|
|
|
ADDF F2, F4, F6 |
|
|
|
ДК |
АО |
ИО11 |
ИО12 |
ИО21 |
ИО22 |
ФР |
|
. . . . . . |
|
|
|
|
ДК |
АО |
ИО |
ФР |
|
|
|
. . . . . . |
|
|
|
|
|
ДК |
АО |
ИО |
ФР |
|
|
LOAD F8, 0(R2) |
|
|
|
|
|
|
ДК |
АО |
ИО |
ФР |
|
Фиг. 5.3.2.14. Конфликт при запис в регистровото СОЗУ
1.
Първият подход се състои в
задържане на командата LOAD до момента, когато командата ADDF
встъпи в етап ФР ;
2.
Вторият подход се състои в
подтискане (скриване) на резултата, който получава командата за събиране ADDF,
в момента на конфликта, т.е. управлението на тази команда се променя така, че
тя не записва своя резултат. В тази ситуация достъпът до регистър F2 на
командата LOAD е свободен и нейното изпълнение завършва. Своят резултат
команда ADDF, или с други думи устройството за събиране може да запише
след време, когато някоя от следващите команди изконсумира съдържанието на
регистър F2. Този подход обаче води до значително усложняване на логиката за
управление изпълнението на следващите операции, където използването на
стойността в регистър F2 може да бъде непредвидимо многократно. Последните
комбинации следва да се откриват от компилатора, а в същото време незаписването
на резултата на операция събиране е свързано с блокиране на устройството за
събиране и невъзможността за неговото по-нататъшно повторно използване.
Възможно е дублиране на командата ADDF на по-късни места в текста на
програмата, което също задължава компилатора.
Предвид сложността на изложените решения, особено на второто, обикновено откриването на този тип конфликти се търси върху ранните стадии на конвейера. Така се налага да се търсят конфликти от една страна между команди с ПЗ, от друга страна между команди с ПЗ и ФЗ, и от трета страна само между команди с ФЗ. С изключение на командите за трансфер (четене/запис) на данни с ПЗ, командите за трансфер на данни между регистрите с ПЗ и ФЗ, командите на аритметиката с ФЗ и на аритметиката с ПЗ са добре разделени. Добрата разделимост се изразява в това, че при достатъчен обем на СОЗУ за работа с ФЗ и ПЗ, конфликтите са изключения. В резултат на това множеството конфликтни команди се намалява по обем и включва преди всичко командите за трансфер на данни с ПЗ и команди за разместване на данни в регистрите за данни с ПЗ. Това облекчаване на управлението на конвейера представлява допълнителен мотив за поддържане на разделни СОЗУ за данни с ФЗ и ПЗ. Основното достойнство на този мотив се състои в това, че удвоеният брой на регистрите от една страна и увеличената пропускателна способност на конвейера от друга страна, се постига без увеличаване на броя на портовете за всеки от регистровите набори.
Ако предположим, че всички конфликти в конвейера се откриват още на етапа ДК, то преди зареждането на командите за изпълнение на операциите във функционалните устройства, трябва да бъдат изпълнени следните 3 проверки:
1.
Проверка за структурни конфликти. Ако такива има, тогава командата се задържа до
освобождаване на функционалното устройство или на порта за запис, ако той е
необходим ;
2.
Проверка за конфликти по данни
от тип RAW. Ако такива има, тогава
командата се задържа докато регистрите, посочени като източник на операнди, са
указани и като регистри за запис на резултат ;
3.
Проверка за конфликти по данни
от тип WAW. Това е проверка за това, че
командите, които се намират в конвейерните станции ИО1 и ИО2, не посочват за
поместване на своите резултати, регистъра за резултата, който заявява
командата. В противен случай придвижването на командата, която се намира в
началната степен ДК, се задържа.
Въпреки, че
логиката за откриване на конфликти за многотактните операции с плаваща запетая
е малко по-сложна, концептуално тя не се отличава от съответната логика за
целочисления конвейер. Същото твърдение се отнася и до ускореното прехвърляне
(ускорения трансфер) на данни. Логиката на ускорения трансфер се основава на
проверката, дали указаният регистър на резултата за конвейерните степени ИО/ФР
представлява регистър на операнд за команда с ПЗ. Ако е налице такова
съвпадение, трансферът на данни се управлява по съответния вход на
мултиплексора (вижте по-горе фигура 5.3.2.5).
Многотактните операции с ПЗ създават също нови проблеми за механизма на
прекъсване.
Следващият раздел е:
5.3.3. Конвейерна и суперскаларна обработка