gemm

Ikko Lv3

gemm

矩阵乘法

访存3+1次

1
2
3
4
5
6
7
8
for (int m = 0; m < M; m++) {
for (int n = 0; n < N; n++) {
C[m][n] = 0;
for (int k = 0; k < K; k++) {
C[m][n] += A[m][k] * B[k][n];
}
}
}
1
2
3
4
5
C = [[0] * N for _ in range(M)]
for m in range(M):
for n in range(N):
for k in range(K):
C[m][n] += A[m][k] * B[k][n]

计算拆分

将输出的计算拆分为 1×4 的小块,即将 维度拆分为两部分。计算该块输出时,需要使用矩阵1的 1 行,和矩阵2的 4 列
访存3+1/4次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
for (int m = 0; m < M; m++) {
for (int n = 0; n < N; n += 4) {
C[m][n + 0] = 0;
C[m][n + 1] = 0;
C[m][n + 2] = 0;
C[m][n + 3] = 0;
for (int k = 0; k < K; k++) {
C[m][n + 0] += A[m][k] * B[k][n + 0];
C[m][n + 1] += A[m][k] * B[k][n + 1];
C[m][n + 2] += A[m][k] * B[k][n + 2];
C[m][n + 3] += A[m][k] * B[k][n + 3];
}
}
}

向量化

向量化通过使用硬件的SIMD(单指令多数据)指令来一次性处理多个数据元素,从而显著提高计算效率。我们可以从以下几个方面来理解这个过程。
C0[0:3] += A0[0:3] * B0[0];
等效于:
C0[0] += A0[0] * B0[0];
C0[1] += A0[1] * B0[0];
C0[2] += A0[2] * B0[0];
C0[3] += A0[3] * B0[0];
可以减小访存次数,并且并行计算

  • Title: gemm
  • Author: Ikko
  • Created at : 2025-02-10 13:46:21
  • Updated at : 2025-02-10 16:27:34
  • Link: https://redefine.ohevan.com/2025/02/10/gemm/
  • License: This work is licensed under CC BY-NC-SA 4.0.
 Comments
On this page
gemm