1. 다음 C code를 RISC-V 어셈블리로 번역하시오.
단, 변수 f, g, h는 x5, x6, x7 레지스터에 위치해 있다고 가정한다. 최소한의 명령어를 사용하시오.f = g + (h - 5);
addi x5, x7, -5
add x5, x6, x5
2. 다음 C code를 RISC-V 어셈블리로 번역하시오.
단, 변수 f, g, h, i, j는 x5, x6, x7, x28, x29 레지스터에 위치해 있고, A와 B의 base address는 x10, x11레지스터에 위치해 있다고 가정한다. 배열 A, B의 원소는 8-byte word로 가정한다.B[8] = A[i] + A[j];
slli x30, x28, 3 // x30 = i * 8
add x30, x10, x30 // x30 = base + 8i
ld x31, 0(x30) // x31 = A[i]
slli x30, x29, 3 // x30 = j * 8
add x30, x10, x30 // x30 = base + 8j
ld x30, 0(x30) // x30 = A[j]
add x31, x31, x30 // x31 = A[i] + A[j]
sd x31, 64(x11) // B[8] = A[i] + A[j]
3. 주어진 명령어의 타입과 16진수 표현을 작성하시오.
sw x5, 32(x30)
type: S
+----------------------------------------------------+
| imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode |
+----------------------------------------------------+
| 32[11:5] | 5 | 30 | | 32[4:0] | sw |
+----------------------------------------------------+
+-------------------------------------------------+
| 0000001 | 00101 | 11110 | 010 | 00000 | 0100011 |
+-------------------------------------------------+
00000010010111110010000000100011 = 0x025F2023
4-1. PC가 0x20000000으로 설정되어 있을 때 RISC-V jal instruction으로 도달할 수 있는 주소의 범위는 무엇인가?
the length of immediate field is 20-bit.
-> offset: 21-bit
Target_addr = PC + imm << 1 = 0x20000000 + imm << 1
offset 최솟값 = -2^20 = -1,048,576 = 0xFFF00000
offset 최대값 = 2^20 - 2 = 1,048,574 = 0x000FFFFE
range
= [PC+FFF00000, PC+0x000FFFFE]
= [0x1FF00000, 0x200FFFFE]
= [535,822,336, 537,919,486]
4-2. PC가 0x20000000으로 설정되어 있을 때 RISC-V beq instruction으로 도달할 수 있는 주소의 범위는 무엇인가?
the length of immediate field is 12-bit.
-> offset: 13-bit
Target_addr = PC + imm << 1 = 0x2000000 + imm << 1
offset 최솟값 = -2^12 = -4,096 = 0xFFFFF000
offset 최대값 = 2^12 - 2 = 4,094 = 0x00000FFE
range
= [PC + 0xFFFFF000, PC + 0x00000FFE]
= [0x1FFFF000, 0x20000FFE]
= [536,866,816, 536,875,006]
5. 다음 RISC-V loop가 있다.
LOOP: beq x6, x0, DONE addi x6, x6, -1 addi x5, x5, 2 jal x0, LOOP DONE:
5-1. x6은 10으로, x5는 0으로 초기화 되어 있을 때 x5의 최종값을 구하여라.
The code is the same as this C code.
int i = 10
int result = 0;
while (i != 0) {
i--;
result += 2;
}
During 10 loops, 2 is added to x5.
So, the final value of x5 is 20.
5-2. 위 loop와 동일한 C code를 작성하여라. x5와 x6는 int acc와 int i로 가정한다.
while (1) {
if (i == 0) break;
i = i - 1;
acc = acc + 2;
}
or
while (i != 0) {
i--;
acc += 2;
}
5-3. x6가 N으로 초기화 된다고 가정할 때 몇 개의 instruction이 실행되는가?
N번 동안 inner loop의 instructions를 반복하고 x6 == 0일 때 beq instruction을 실행해 loop를 탈출하므로 총 4*N + 1개의 instruction이 실행된다.
5-4. 위 RISC-V loop에서
beq x6, x0, DONE을blt x6, x0, DONE으로 대체하고, 이와 동등한 C code를 작성하여라.
LOOP: blt x6, x0, DONE
addi x6, x6, -1
addi x5, x5, 2
jal x0, LOOP
DONE:
while (i >= 0) {
i = i - 1;
acc = acc + 2;
}
6. 주어진 프로그램에서 실행되는 연산의 70%는 arithmetic, 10%는 load/store, 20%는 branch라고 가정하자.
6-1. arithmetic instruction은 2 cycles, load/store instruction은 6 cycles, branch instruction은 3 cycles을 요구할 때 평균 CPI를 구하여라.
IC = N
IC_a = 0.7N
IC_ls = 0.1N
IC_b = 0.2N
CPI_a = 2
CPI_ls = 6
CPI_b = 3
Cycles = 2*0.7N + 6*0.1N + 3*0.2N = 2.6N
CPI_avg = Cycles/IC = 2.6N/N = 2.6
6-2. 위 프로그램에서 25%의 성능 개선이 이루어졌다. 만약 load/store, brance instructions는 이 개선의 영향을 받지 않을 때 arithmetic instructions의 평균 Cycle은 얼마인가?
Performance = 1/Execution_Time
Improved_Performance = 1.25 * Performance
Improved_Excution_Time = 0.8 * Execution_Time
Execution_Time = CPI * IC / Clock_Rate
new_CPI_a = x
new_CPI_avg = 0.7x + 1.2
Improved_Execution_Time
= new_CPI_avg * IC / Clock_Rate
= (0.7x + 1.2) * IC / Clock_Rate
= 0.8 * 2.6 * IC / Clock_Rate
0.7x + 1.2 = 2.08, 0.7x = 0.88
x 1.257
6-3. 위 프로그램에서 50%의 성능 개선이 이루어졌다. 만약 load/store, brance instructions는 이 개선의 영향을 받지 않을 때 arithmetic instructions의 평균 Cycle은 얼마인가?
Performance = 1/Execution_Time
Improved_Performance = 1.5 * Performance
Improved_Execution_Time = 1/1.5 * Execution_Time
Execution_Time = CPI * IC / Clock_Rate
new_CPI_a = x
new_CPI_avg = 0.7x + 1.2
Improved_Execution_Time
= new_CPI_avg * IC / Clock_Rate
= (0.7x + 1.2) * IC / Clock_Rate
= 1/1.5 * 2.6 * IC / Clock_Rate
0.7x + 1.2 = 2.6/1.5, 0.7x = 26/15 - 1.2
x 0.762