矩阵乘法定义
其他性质
矩阵分块
计算特点:
A的大小是M*K,B的大小是K*N,结果矩阵C的大小是M*N。
标准做法是C的每个元素为A的一行与B一列的内积,C参考程序:
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++j) {
double dot = 0.0;
for (int z = 0; z < K; ++z) {
dot += A(i, z) * B(z, j);
}
C(i, j) = dot;
}
}
1. A的每行计算是独立的,可以单独取出A的第n行,与B运算后得到C的第n行。
2. B的每列计算是独立的,可以单独取出B的第m列,与A计算后可以得到C的第m列。
3. B的第k行元素只与A的第k列的元素进行交互。可以认为取出B的第k行与A的第k列元素,以此计算出C的一层,总共K层“千层饼”叠加得到C(OpenBLAS gemm从零入门 - 知乎)。(上面cij的累加项只考虑第k项便是第k层)。这里其实也可以看成是把A和B分别划分为宽度和高度分别为1的分块矩阵然后做矩阵乘法。当前也可以划分为其他高度。
这三个理解可以参考变换下面程序的3个loop不同顺序(假设C已经初始化为0),例如把K循环放到最外层,或者N循环放最外层。
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++j) {
for (int z = 0; z < K; ++z) {
C(i, j) += A(i, z) * B(z, j);
}
}
}
ref