МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ «ЛЬВІВСЬКА ПОЛІТЕХНІКА»
ІКТА
Кафедра ЗІ
/
Звіт
до лабораторної роботи №4
з курсу: «Архітектура комп’ютерних систем»
на тему: «Дослідження конвеєрного виконання інструкцій рухомої коми»
Мета роботи
Опанування технікою конвеєрного виконання RISC інструкцій для операндів формату рухомої коми.
Завдання
Засобами архітектурного симулятора WinMIPS64 машини з 64-розрядною RISC архітектурою MIPS64 дослідити конвеєрне виконання фрагментів машинних програм, що команди опрацювання операндів в форматі з рухомою комою. Виявити наявні залежності (небезпеки) даних і керування, оптимізувати програмний код та дослідити дію запропонованої оптимізації.
За результатами проведених лабораторних досліджень оформити звіт та захистити його.
Початок виконання роботи
; hail.s
; Hailstone numbers iteration
; If number is odd, multiply by 3 and add 1
; If number is even, divide it by 2
; repeat this iteration until number is 1
.data
number: .word 6 ; this is input number - change it!
max: .word 0 ; max number so far
.text
start: ld r1,number(r0) ; program start
loop: andi r3,r1,1 ; test odd or even
beqz r3,even
odd: dadd r2,r1,r1 ; times 2
dadd r1,r2,r1 ; times 3
daddi r1,r1,1 ; plus 1
j over
even: dsrl r1,r1,1 ; divide by 2
over: ld r4,max(r0)
slt r3,r4,r1 ; compare with max
beqz r3,skip
sd r1,max(r0) ; new max
skip: slti r3,r1,2 ; test for finished
beqz r3,loop
halt
Код початкової програми мовою асемблера
Pass 1 completed with 0 errors
; hail.s
; Hailstone numbers iteration
; If number is odd, multiply by 3 and add 1
; If number is even, divide it by 2
; repeat this iteration until number is 1
00000000 .data
00000000 000000000000001b number: .word 27 ; this is input number - change it!
00000008 0000000000000000 max: .word 0 ; max number so far
00000000 .text
00000000 dc010000 start: ld r1,number(r0) ; program start
00000004 30230001 loop: andi r3,r1,1 ; test odd or even
00000008 18030004 beqz r3,even
0000000c 0021102c odd: dadd r2,r1,r1 ; times 2
00000010 0041082c dadd r1,r2,r1 ; times 3
00000014 60210001 daddi r1,r1,1 ; plus 1
00000018 08000001 j over
0000001c 0020087a even: dsrl r1,r1,1 ; divide by 2
00000020 dc040008 over: ld r4,max(r0)
00000024 0081182a slt r3,r4,r1 ; compare with max
00000028 18030001 beqz r3,skip
0000002c fc010008 sd r1,max(r0) ; new max
00000030 28230002 skip: slti r3,r1,2 ; test for finished
00000034 1803fff3 beqz r3,loop
00000038 04000000 halt
Pass 2 completed with 0 errors
Code Symbol Table
start = 00000000
loop = 00000004
odd = 0000000c
even = 0000001c
over = 00000020
skip = 00000030
Data Symbol Table
number = 00000000
max = 00000008
Результат перевірки
/
Бачимо, що програма виконується 173 цикли з середнім значенням продуктивності 2.403 циклів на інструкцію. Було здійснено 74 пригальмовування RAW та 23 пригальмовувань при виборі гілки. З цього робимо висновок, що програма працює неефективно та потребує оптимізації.
Оптимізація коду
Виконаємо оптимізацію коду, а саме змінимо структуру виконання таким чином, щоб мінімізувати послідовність команд кожної гілки (парне/непарне). Можемо не виконувати порівняння числа з max, якщо воно було парним та поділилося на 2:
; hail.s
; Hailstone numbers iteration
; If number is odd, multiply by 3 and add 1
; If number is even, divide it by 2
; repeat this iteration until number is 1
.data
number: .word 27 ; this is input number - change it!
max: .word 0 ; max number so far
.text
start: ld r1,number(r0) ; program start
loop: andi r3,r1,1 ; test odd or even
bnez r3,odd
even: dsrl r1,r1,1 ; divide by 2
j skip
odd: dadd r2,r1,r1 ; times 2
dadd r1,r2,r1 ; times 3
daddi r1,r1,1 ; plus 1
over: ld r4,max(r0)
slt r3,r4,r1 ; compare with max
beqz r3,skip
sd r1,max(r0) ; new max
skip: slti r3,r1,2 ; test for finished
beqz r3,loop
halt
Перевіримо код за допомогою asm:
Pass 1 completed with 0 errors
; hail.s
; Hailstone numbers iteration
; If number is odd, multiply by 3 and add 1
; If number is even, divide it by 2
; repeat this iteration until number is 1
00000000 .data
00000000 000000000000001b number: .word 6 ; this is input number - change it!
00000008 0000000000000000 max: .word 0 ; max number so far
00000000 .text
00000000 dc010000 start: ld r1,number(r0) ; program start
00000004 30230001 loop: andi r3,r1,1 ; test odd or even
00000008 1c030002 bnez r3,odd
0000000c 0020087a even: dsrl r1,r1,1 ; divide by 2
00000010 08000007 j skip
00000014 0021102c odd: dadd r2,r1,r1 ; times 2
00000018 0041082c dadd r1,r2,r1 ; times 3
0000001c 60210001 daddi r1,r1,1 ; plus 1
00000020 dc040008 over: ld r4,max(r0)
00000024 0081182a slt r3,r4,r1 ; compare with max
00000028 18030001 beqz r3,skip
0000002c fc010008 sd r1,max(r0) ; new max
00000030 28230002 skip: slti r3,r1,2 ; test for finished
00000034 1803fff3 beqz r3,loop
00000038 04000000 halt
Pass 2 completed with 0 errors
Code Symbol Table
start = 00000000
loop = 00000004
even = 0000000c
odd = 00000014
over = 00000020
skip = 00000030
Data Symbol Table
number = 00000000
max = 00000008
/
Після проведення оптимізації кількість RAW Stalls зменшилася до 50, а кількість Branch Taken Stalls зменшилася до 15. Також покращився показник кількості циклів на інструкцію, відповідно зменшилася кількість тактів та інструкцій. Для подальшої оптимізації можна увімкнути Forwarding та Branch Target Buffer:
/
Часові характеристики коду значно покращилися: 99 циклів, 58 інструкції, 1.707 циклів на інструкцію, 21 RAW Stalls, 10 Branch Taken Stalls. Також бачимо, що додалося 6 Branch Misprediction Stalls.
Висновок
На цій лабораторній роботі я виконав оптимізацію асемблерного коду для обчислення послідовності чисел Сиракузької послідовності (гіпотеза Коллатца). Гіпотеза Коллатца полягає в тому, що будь-яке число можна перетворити в одиницю, в даному випадку за допомогою системи умов «якщо число парне, ділимо його на 2, а якщо непарне – множимо на 3 і додаємо 1».