No tak, ale te dokumenty dotyczą czasów pentium MMX. Po wprowadzeniu (bodajże P3 albo może p4 ) zmienił się sposób optymalizacji. Różnica jest taka, że nie ma już jednostek dekodujących D0, D1, D2. Teraz procesor to jest zestaw kilku microprocesorów o różnym przeznaczeniu. Np. są 2 jednostki ALU z podwojnym zegarem, jednostki FPU move, FPU Execute, integer operation, memory load, memory save. Kazdy rozkaz zajmuje jedna lub kilka jednostek, przy czym wykonywanie jest niezalezne... tzn. ze jezeli mamy:
mov eax, [memory]
add ebx, ecx
mov ecx, edx
mov edx, ebp
fadd
imul
....
to rozkaz mov eax,[memory] moze zostac wykonany na koncu tej listy rozkazow, bo uzywa jednostki memory load, ktora jest najwolniejsza. Ale poniewaz pozniejsze rozkazy nie potrzebuja wyniku operacji, to moga byc wykonywane dalej. To czy jakiś rozkaz się wykona od razu czy będzie czekać na swoją kolej, zależy przedewszystkim od dwoch czynników:
1) czy jednostka wykonawcza jest zajęta czy wolna
2) czy trzeba czekać na wynik poprzedniej operacji
w przypadku 2) rozkazy
add edx, ecx
mov ecx, eax
nie beda sie blokowac gdyz wynik pierwszej operacji jest zabisany w edx, natomiast ecx jest "wolny" od razu (sluzy tylko na wstepie jako źródło wartości).
Co do punktu 1) to trzeba przeczytać dokument intela "IA-32 Intel? Architecture Optimization Reference Manual", ftp://download.intel.com/design/Pentium … 896612.pdf tam jest lista rozkazów z wypiską których jednostek wykonawczych one używaja.
Aha, no i jeszcze jest coś takiego jak latency i throughput. Latency oznacza ile cykli trzeba czekać na wynik, natomiast throughput ile cykli potrzeba aby wykonać/zdekodować kolejną instrukcję.
Dla przykładu ów ROL ma 0.5 throughput (następna instrukcja może zostać zdekodowana i przekazana do wykonania) po 0.5 cykla, natomiast ma 1 cykl latency (czyli wynik jest znany po 1 cyklu). a 1 cykl dlatego ze wykonanie tej instukcji jest w jednostce integer operation ktora chodzi na zegarze procesora (a nie na x2 jak jednostki ALU).
[Edit]
Jeszcze odnośnie instrukcji XCHG AL, AH. Wykonuje się ona "zawsze" 1.5 cykla (latency) i ma 1 cykl throughput. ROL AX,8 wykonuje się 1 cykl na większości procesorów, albo 4 cykle (to jest tylko na rodzinie procesorów 0xF2). Ponadto nie występuje tutaj coś takiego jak "problem emulacji rejestrów", bo jest wykorzystywana tylko część rejestru a nie całość. Jedyne co może wystąpić to "partial registry stall" albo "registry stall", czyli np.:
rol eax, 8
mov al, ah
druga instrukcja, czeka na wynik pierwszej, gdyż wartość 'ah' jest zależna od wykonania poprzedniej instrukcji. Bynajmniej nie wynika to z podziału rejestrów. Problem pojawia się jedynie w sytuacji gdy chcemy użyć rejestru, który wcześniej posłużył jako rejestr docelowy.