[Computer Architecture] Assignment 1 - Assembly
"RISC-V Assembly"
[Objective]
Weight Stationary 방식의 C += A x B Matrix 연산을 Assembly 언어로 구현하기
[Kite Description]
· Kite는 RISC-V 5-Stage Pipeline Modeling에 사용하는 Simulator
▣ Program Code
<program_code>
· PC = 4부터 시작 (beq의 PC = 4)
· 명령어 하나 = 4-Byte (remu의 PC = 8)
· 전체 6개의 명령어 → 전체 Code Size = 24-Byte (4 ~ 28)
· 대소문자 구분 X
▣ Register State
** x0은 항상 0으로 변경 불가
<mem_state>
· 주소는 반드시 8의 배수
· 64-bit 데이터
[Background]
<행렬 곱셈 연산>
· C[i][j] = ∑A[i][k] x B[k][j]
<Output-Stationary>
· 결과 값(C[i][j])을 Register에 유지 → 계산 끝날 때만 메모리에 저장① A행 + B열 Read
② 계속 누적
③ 마지막에 저장
△ 메모리 Write 적음
① B 값 고정
② A를 바꿔가며 계산
② A를 바꿔가며 계산
③ 결과(C)는 계속 메모리에 반영
△ Weight(B)를 계속 재사용
▼ 메모리 Write 많음
[Implementation]
· Weight-Stationary 방식으로 C += A x B 구현
▣ Register State
· x10 = 1024, x11 = 2016, x12 = 3008로 초기화
▣ Memory State
▣ Code Flow
1 2 3 4 5 6 7 8 | for (k = 0; k < K; k++) { for (j = 0; j < N; j++) { weight = B[k][j]; for (i = 0; i < M; i++) { C[i][j] += A[i][k] * weight; } } } | cs |
① Weight Stationary 방식이므로 Weight인 B 행렬 먼저 고정
② Loop를 돌며 A 행렬과 C 행렬 값 Load
③ A 행렬과 B 행렬(Weight)를 곱한 후, C 행렬 값과 누산
▣ Code Description
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | addi x3, x0, 0 # Initialize k = 0 LOOP_k: bge x3, x15, MMA_WS # If k >= K, then finish (K = 4) addi x4, x0, 0 # Next k -> Return to j = 0 LOOP_j: bge x4, x14, NEXT_k # If j >= N, then k++ (N = 6) # Calculate B[k][j] Memory Address mul x16, x3, x14 # x16 = k x N add x16, x16, x4 # x16 = (k x N) + j slli x16, x16, 3 # x16 = {(k x N) + j} x 2^3(= 8) add x16, x11, x16 # x16 = B Base Address + Offset ld x23, 0(x16) # Load B[k][j] Value from Calculated Address to x23 Register addi x5, x0, 0 # Next j -> Return to i = 0 LOOP_i: bge x5, x13, NEXT_j # If i >= M, then j++ (M = 10) # Calculate A[i][k] Memory Address mul x17, x5, x15 # x17 = i x K add x17, x17, x3 # x17 = (i x K) + k slli x17, x17, 3 # x17 = {(i x K) + k} x 2^3(= 8) add x17, x10, x17 # x17 = A Base Address + Offset ld x24, 0(x17) # Load A[i][k] Value from Calculated Address to x24 Register # Calculate C[i]][j] Memory Address mul x18, x5, x14 # x18 = i x N add x18, x18, x4 # x18 = (i x N) + j slli x18, x18, 3 # x18 = {(i x N) + j} x 2^3(= 8) add x18, x12, x18 # x18 = C Base Address + Offset ld x25, 0(x18) # Load C[i][j] Value from Calculated Address to x25 Register # MAC mul x19, x24, x23 # x19 = A[i][k] x B[k][j] add x25, x25, x19 # x25 = C[i][j] + (A[i][k] x B[k][j]) # Update C[i][j] sd x25, 0(x18) # Update C[i][j] Value in C[i][j] Memory Address addi x5, x5, 1 # i++ beq x0, x0, LOOP_i # Return to LOOP_i and retry Loop NEXT_j: addi x4, x4, 1 # j++ beq x0, x0, LOOP_j # Return to LOOP_j and retry Loop NEXT_k: addi x3, x3, 1 # k++ beq x0, x0, LOOP_k # Return to LOOP_k and retry Loop MMA_WS: jalr x0, 0(x0) # Finish | cs |
① B[k][j]의 메모리 주소를 계산한 후, 해당 메모리 위치에 있는 값을 Load
② B[k][j]의 값을 고정하고, i = 0 ~ M-1까지 반복하면서 A[i][k]와 C[i][j]의 메모리 주소를 계산하여 해당 메모리 위치의 값을 Load
③ C[i][j] += A[i][k] x B[k][j] 계산을 한 후, C[i][j]를 메모리에 다시 저장
④ i = 0 ~ M-1 반복 → j = 0 ~ N-1 반복 → k = 0 ~ K-1 반복
[Reference]
· assembly (Computer Architecture) - William J. Song
댓글
댓글 쓰기