从矩阵乘法的不同计算方式来看局部性原理
来源:互联网 发布:数据采集系统标准规范 编辑:程序博客网 时间:2024/04/29 16:51
今天碰到的关于矩阵乘法不同情况下运算速度的问题,隐约记得是因为缓存的问题,后来突然想起来CSAPP那本书上讲过这个东西的,就是通过矩阵乘法三重循环的不同顺序来讲的局部性原理的,所以翻过来又看了一下。
两个矩阵A,B相乘得到C【为了方便起见,把它们都看成n*n的方阵】经典的做法就是用三重循环来实现,但是具体这三重循环如何进行排列,就非常的有讲究。
假设n是一个非常大的数,也就意味着如果跨行的话,必然不会缓存命中,假设只有一个告诉缓存,其块大小为32字节,也就说一个块只能存4个double
经典做法ijk和jik
for(i=0;i<n;++i) for(j=0;j<n;++j) { double sum=0; for(k=0;k<n;++k) sum+=a[i][k]*b[k][j]; c[i][j]+=sum; }for(j=0;j<n;++j) for(i=0;i<n;++i) { double sum=0; for(k=0;k<n;++k) sum+=a[i][k]*b[k][j]; c[i][j]+=sum; }
这两种方法的复杂度分析是一样的.AB之中必有一个是每次都不命中的,剩下一个每四个不命中一次。
jki和kji版本
for(j=0;j<n;++j) for(k=0;k<n;++k) { double r = b[k][j]; for(i=0;i<n;++i) c[i][j]+=a[i][k]*r; }for(k=0;k<n;++k) for(j=0;j<n;++j) { double r = b[k][j]; for(i=0;i<n;++i) c[i][j]+=a[i][k]*r; }
这两种方法是最差的方法,因为每次c和a两个都完全不命中
最好的方法kij和ikj版,即让最频繁变动的层不动
for(k=0;k<n;++k) for(i=0;i<n;++i) { double r = a[i][k]; for(j=0;j<n;++j) c[i][j]+=r*b[k][j]; }for(i=0;i<n;++i) for(k=0;k<n;++k) { double r = a[i][k]; for(j=0;j<n;++j) c[i][j]+=r*b[k][j]; }
这样最里面的循环那层,每次访问都保证了空间局部性
所以可以看到,虽然矩阵乘法非常的简单,但是具体实现起来,其优化所要做到的细节还是非常多的,涉及到访存的问题还是比较复杂的,尤其是对于局部性的理解。
0 0
- 从矩阵乘法的不同计算方式来看局部性原理
- 基于CPU访存局部性原理下的矩阵乘法实现
- 关于矩阵乘法按照列乘行的方式来看
- 从多元方程组到矩阵计算的乘法法则
- 程序的局部性原理
- 程序的局部性原理
- CSAPP第五次实验(cahce) 局部性对矩阵乘法的影响
- 矩阵乘法的并行计算
- 大数乘法的计算原理
- 动态规划 的方法求矩阵乘法的最少计算加括号方式
- 用多线程并发的方式来计算两个矩阵的乘法
- 局部性原理
- 局部性原理
- 局部性原理
- 局部性原理
- 局部性原理
- Hadoop 稀疏矩阵乘法的MapReduce计算
- 计算矩阵运算的乘法次数
- Servlet的三种创建方式
- C中常量字符串和字符数组的区别
- 系统存在多个opencv库导致的caffe运行异常:undefined symbol imencode imread
- synchronized原理浅析
- CAN总线协议
- 从矩阵乘法的不同计算方式来看局部性原理
- layer如何关闭以及父页面如何访问IFRAME页面的JS方法属性
- 2017年3月25日工作日志:Jquery使用小结[绑定事件判断、select标签、军官证正则]
- TextView中ellipsize属性
- 鸭子知多少
- :hover放前面和放后面的区别
- Hibernate缓存机制
- $.ajax()详解
- springmvc使用freemarker