矩阵乘法优化

问题描述

矩阵乘法 C = A × B,三层嵌套循环。不同的循环排序导致完全不同的缓存性能。

六种循环顺序

按不命中率从优到劣分为三个梯队:

第一梯队(不命中率

$kij:  for k, for i, for j → C[i][j] += A[i][k] * B[k][j]$
$ikj:  for i, for k, for j → C[i][j] += A[i][k] * B[k][j]$
  • A[i][k] 提取到寄存器,不重复访问
  • 内层循环 j 遍历 C 和 B 的行
  • 空间局部性最佳

第二梯队(不命中率

$ijk:  for i, for j, for k → C[i][j] += A[i][k] * B[k][j]$
$jik:  for j, for i, for k → C[i][j] += A[i][k] * B[k][j]$

第三梯队(不命中率

$jki:  for j, for k, for i → C[i][j] += A[i][k] * B[k][j]$
$kji:  for k, for j, for i → C[i][j] += A[i][k] * B[k][j]$

关键优化:ikj 模式

在 ikj 模式中:

  • A[i][k] 被提取到寄存器(标量替代),完全消除对 A 的重复读取
  • 内层 j 循环对 C 和 B 进行步长为 1 的遍历
  • 充分利用

根本原因

C 语言中数组是行优先(Row-major)存储,内层循环沿 j 遍历是最自然的。


相关笔记:

链接到