矩阵乘法的玄学优化

在一般矩阵乘法中,采用 ijk 枚举顺序,即:

Matrix operator * (const Matrix &x) const {
      Matrix y;
      for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                  for(int k=1;k<=n;k++)
                        y.num[i][j]+=num[i][k]*x.num[k][j];
      return y;
}

但实际上,这种枚举顺序会影响矩阵乘法的常数

C/C++ 中,本质上按行优先储存数据, ijk 枚举顺序将会使得 x.num[k][j] 在内存中跳着枚举,降低效率

故更换顺序为 ikj ,即:

Matrix operator * (const Matrix &x) const {
    Matrix y;
    for (int i = 0; i < 4; i++)
        for (int k = 0; k < 4; k++) {
            ll s = Num[i][k];
            for (int j = 0; j < 4; j++)
                y.Num[i][j] += s * x.Num[k][j];
        }
    return y;
}

使得枚举顺序在内存中连续,可以提高一定效率

好像据实验测试,能快 5 倍

posted @ 2021-01-29 15:17  JustinRochester  阅读(471)  评论(0编辑  收藏  举报