owned this note
owned this note
Published
Linked with GitHub
# Homework2: RISC-V Toolchain
## Dot Product
### Pick up a assembly program from Homework1
* choose Dot Product from [段雅培](https://hackmd.io/@kaeteyaruyo/risc-v-hw1)
### Rewrite the C code
```cpp=
void _start() {
int a[3] = {1,2,3};
int b[3] = {-4,-5,6};
int sum = 0;
int i;
for(i=0;i<3;i++)
sum=sum+a[i]*b[i];
volatile char *tx = (volatile char *)0x40002000;
const char *result = "The inner product of two vectors is ";
while (*result){
*tx = *result;
result++;
}
*tx = (char)((sum +'0'));
*tx = '\n';
}
```
:::spoiler ### Handwritten Assembly code from 段雅培
```cpp=
.data
arr1: .word 1, 2, 3 # a[3] = {2, 4, 6}
arr2: .word 4, 5, 6 # b[3] = {8, 10, 12}
len: .word 3 # array length = 3
str: .string "The inner product of two vectors is "
.text
# s1 = arr1 base address
# s2 = arr2 base address
# s3 = array length
# s4 = sum
# t0 = i
# t1 = a[i]
# t2 = b[i]
# t3 = a[i] * b[i] (assume no overflow, lower 32 bits)
main:
la s1, arr1 # s1 = a
la s2, arr2 # s2 = b
lw s3, len # s3 = 3
add s4, x0, x0 # sum = 0
add t0, x0, x0 # i = 0
jal ra, loop # jump to for loop
jal ra, print # jump to for loop
li a7, 10 # end program
ecall
loop:
lw t1, 0(s1) # t1 = a[i]
addi s1, s1, 4 # ++a (address move forward)
lw t2, 0(s2) # t2 = b[i]
addi s2, s2, 4 # ++b
mul t3, t1, t2 # t3 = a[i] * b[i]
add s4, s4, t3 # sum += a[i] * b[i]
addi t0, t0, 1 # ++i
blt t0, s3, loop # if i < 3, go to loop
ret # else, return to main
print:
la a0, str # load string
li a7, 4 # print string
ecall
add a0, s4, x0 # load result
li a7, 1 # print integer
ecall
ret # go back to main
```
:::
:::spoiler ### Compiler optimized Assembly code by O3
```cpp=
DotProduct: file format elf32-littleriscv
Disassembly of section .text:
00010054 <_start>:
10054: 000107b7 lui a5,0x10
10058: 08878793 addi a5,a5,136 # 10088 <_start+0x34>
1005c: 05400713 li a4,84
10060: 400026b7 lui a3,0x40002
10064: 00e68023 sb a4,0(a3) # 40002000 <__global_pointer$+0x3fff0750>
10068: 00178793 addi a5,a5,1
1006c: 0007c703 lbu a4,0(a5)
10070: fe071ae3 bnez a4,10064 <_start+0x10>
10074: 03400793 li a5,52
10078: 00f68023 sb a5,0(a3)
1007c: 00a00793 li a5,10
10080: 00f68023 sb a5,0(a3)
10084: 00008067 ret
```
:::
:::spoiler ### Compiler optimized Assembly code by Os
```cpp=
DotProduct: file format elf32-littleriscv
Disassembly of section .text:
00010054 <_start>:
10054: 000107b7 lui a5,0x10
10058: 08c78793 addi a5,a5,140 # 1008c <_start+0x38>
1005c: 400026b7 lui a3,0x40002
10060: 0007c703 lbu a4,0(a5)
10064: 00071e63 bnez a4,10080 <_start+0x2c>
10068: 400027b7 lui a5,0x40002
1006c: 03400713 li a4,52
10070: 00e78023 sb a4,0(a5) # 40002000 <__global_pointer$+0x3fff074c>
10074: 00a00713 li a4,10
10078: 00e78023 sb a4,0(a5)
1007c: 00008067 ret
10080: 00e68023 sb a4,0(a3) # 40002000 <__global_pointer$+0x3fff074c>
10084: 00178793 addi a5,a5,1
10088: fd9ff06f j 10060 <_start+0xc>
```
:::
### Result by O3
```
./emu-rv32i DotProduct
The inner product of two vectors is 4
>>> Execution time: 3523200 ns
>>> Instruction count: 154 (IPS=43710)
>>> Jumps: 36 (23.38%) - 0 forwards, 36 backwards
>>> Branching T=35 (97.22%) F=1 (2.78%)
```
### Result by Os
```
./emu-rv32i DotProduct
The inner product of two vectors is 4
>>> Execution time: 3628300 ns
>>> Instruction count: 192 (IPS=52917)
>>> Jumps: 73 (38.02%) - 36 forwards, 37 backwards
>>> Branching T=36 (97.30%) F=1 (2.70%)
```
:::spoiler ### Readelf by O3
```
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: RISC-V
Version: 0x1
Entry point address: 0x10054
Start of program headers: 52 (bytes into file)
Start of section headers: 588 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 7
Section header string table index: 6
```
:::
:::spoiler ### Readelf by Os
```
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: RISC-V
Version: 0x1
Entry point address: 0x10054
Start of program headers: 52 (bytes into file)
Start of section headers: 592 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 7
Section header string table index: 6
```
:::
### Size by O3
```
text data bss dec hex filename
92 0 0 92 5c DotProduct
```
### Size by Os
```
text data bss dec hex filename
96 0 0 96 60 DotProduct
```