偏个题。
说到这个想起之前朋友和我说到他最近在上一个课。
那个课上,教授要求他们写Cache friendly code。
尤其像矩阵这种很大块的东西,在运算时,会导致cache根本无法完全装下需要使用的数据。
此刻,如果程序没有设计得很有技巧,不断地刷新cache,会需要浪费大量的时间。
所以,他们教了好几种方法去计算矩阵,让整个计算过程中尽量减少cache的重新载入:
以下是引用朋友给我的邮件,作者是@Tian Tan :
先给你说个好玩的。这是我上的一门课的内容,叫high performance computing
这周在超级计算机上做了一个实验,
实验内容是想尽办法优化很小一段代码,比如矩阵乘法。
先说说cache的特点。
当访问内存中一个element的时候,
cpu会把那个element放到cache里面,
同时还会把它临近的elements放进cache。
衡量CPU快慢的一个标准是MFLOPS, 全称为millions of floating point operations per second. 实验的宗旨是写cache friendly code. 直接上例子吧。
A, B, C都是浮点数矩阵
for (i=0; i
for (j=0; j
for (k=0; k
C[i][j] += A[i][k]*B[k][j];
这是个很简单的矩阵乘法算法。但是这么写效率是不高的,
原因在于当N很大的时候,比如2048, 4096,会产生cache conflict。要解释这个术语比较麻烦,
想知道的话去看computer system: a programmer's perspective那本书的第六章。
但是矩阵乘法有别的写法。比如
for (i=0; i
for (k=0; k
for (j=0; j
C[i][j] += A[i][k]*B[k][j];
这种写法交换了k和j的位置,效率应该会比前面那个高些。(
术语是loop permutation)
还有的写法叫loop tiling,
tiling的实质是将大矩阵的乘法变成小的分块矩阵的乘法。
就用上一个例子吧。
for(it=0; it
for(jt=0; jt
for(kt=0; kt
for(i=it; i
for(j=jt; j
for(k=kt; k
C[i][j] += A[i][k]*B[k][j];
其中的T叫tiling size,能整除N。
这样先算小矩阵的话,cache 就能装下参与运算的elements, 对速度提升很大。
在实验中有一道题,
经过优化之后把运行时间从49秒降到13秒了。
矩阵乘法只是最简单例子,不同的code优化方式各异,
但是基本思想一样。
另外,正如上面说的。
使用针对你自己的CPU的编译器,编译器有可能能够识别到你的功能,做出相应的优化。
本文介绍了在高性能计算课程中优化矩阵乘法等操作的方法,通过改变循环顺序和使用分块技术来提高缓存利用率,从而显著提升计算性能。
2420

被折叠的 条评论
为什么被折叠?



