행렬 곱셈에 대한 병렬 표현방법
정방행렬 A,B∈RN×N를 곱하는것을 쿠다로 구현하기 이전에 병렬로 연산하는 방법에 대해서 정리를 하면 다음과 같음. 먼저 각 행렬을 p×p개의 사이즈를 가지는 부분행렬로 나눈 다음에 각각 구간의 곱을 구한다음에 합을 구하는게 병렬처리에 유리함
1. 블록 분할 형태
A=⎣⎢⎢⎢⎢⎡A11A21⋮Ap1A12A22⋮Ap2⋯⋯⋱⋯A1pA2p⋮App⎦⎥⎥⎥⎥⎤,Aij∈Rm×m
- 전체 A는 p×p개의 블록으로 구성
- 각 블록 Aij는 m×m 크기의 부분 정방행렬
예시: p=2, m=2인 경우
A=⎣⎢⎢⎢⎡a11a21a31a41a12a22a32a42a13a23a33a43a14a24a34a44⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎡[a11a21a12a22][a31a41a32a42][a13a23a14a24][a33a43a34a44]⎦⎥⎥⎥⎤
동일 한 형식으로 B도 표현하면 아래와같이 표현됨
A=⎣⎢⎢⎢⎡b11b21b31b41b12b22b32b42b13b23b33b43b14b24b34b44⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎡[b11b21b12b22][b31b41b32b42][b13b23b14b24][b33b43b34b44]⎦⎥⎥⎥⎤
2. 블록 행렬곱(Block Matrix Multiplication)
두 정방행렬 A,B∈R(pm)×(pm)를 같은 방식으로 분할하면
곱 C=AB의 각 블록도 다음과 같이 표현할 수 있음
Cij=∑k=1pAikBkj,i,j=1,…,p
즉,
- C11=A11B11+A12B21+⋯+A1pBp1
- C12=A11B12+A12B22+⋯+A1pBp2
- …
- Cpp=Ap1B1p+Ap2B2p+⋯+AppBpp
위 수식은 전체 행렬곱을 부분 정방행렬 간 곱과 덧셈으로 표현이 가능함. 좀더 일반적인 형태로 표현 하면 다음과같이 나타낼수 있음
Cij=k=1∑pAikBkj,i,j=1,2,…,p
3. CUDA 병렬연산과의 관계성
-
그리드(Grid) 분할
- 전체 행렬을 p×p 그리드로 나누면 ,각 그리드 셀은 크기 m×m인 부분정방행렬(블록)으로 표현 가능
N=p×m,A=⎣⎢⎢⎡A11⋮Ap1⋯⋱⋯A1p⋮App⎦⎥⎥⎤,Aij∈Rm×m
-
블록 단위 연산
- 각 블록 (i,j)에 대해 독립적으로 다음 수식을 계산
Cij=k=1∑pAikBkj
- 이 연산은 GPU의 각 스레드 블록이 “부분행렬 Aik·Bkj 내적 → 합산”을 담당하도록 매핑됩니다.
-
병렬 처리
- p×p 블록 모두를 병렬로 실행하여 전체 C=AB를 완성
- 타일링(shared memory) 기법을 써서 각 블록 내에서 메모리 접근을 최적화하고, 글로벌 메모리 트래픽을 연산속도를 빠르게 구현가능