对于循环次数较为有限的for循环,可通过手工展开该循环达到消除此循环的目的,达到加速运行的目的,下面给出一个代码段实例。
1、for循环体
1 // Q为常数 2 for ( k = 0; k < Q; k++ ) { 3 for ( int j = 0; j < Q; j++ ) { 4 m[k] += fp[z][y][x][j] * mat_M[k][j]; 5 } 6 }
此段代码由两重循环构成,Q为常数,尝试将内层循环展开来消除内层循环。
2、内存循环展开
1 for ( k = 0; k < Q; k++ ) { 2 m[k] = fp[z][y][x][0] * mat_M[k][0] + fp[z][y][x][1] * mat_M[k][1] + fp[z][y][x][2] * mat_M[k][2] + fp[z][y][x][3] * mat_M[k][3] + fp[z][y][x][4] * mat_M[k][4] 3 + fp[z][y][x][5] * mat_M[k][5] + fp[z][y][x][6] * mat_M[k][6] + fp[z][y][x][7] * mat_M[k][7] + fp[z][y][x][8] * mat_M[k][8] + fp[z][y][x][9] * mat_M[k][9] 4 + fp[z][y][x][10] * mat_M[k][10] + fp[z][y][x][11] * mat_M[k][11] + fp[z][y][x][12] * mat_M[k][12] + fp[z][y][x][13] * mat_M[k][13] + fp[z][y][x][14] * mat_M[k][14] 5 + fp[z][y][x][15] * mat_M[k][15] + fp[z][y][x][16] * mat_M[k][16] + fp[z][y][x][17] * mat_M[k][17] + fp[z][y][x][18] * mat_M[k][18]; 6 }
展开内层循环,将两重循环变为一重循环。
3、对比
展开前,代码运行时间为66s,展开后,运行时间51s,运行时间缩短22.7%,运行加速效果还是非常显著,考虑到此段代码为整个程序的运行热点段,对整个程序运行也将带来一定的速度提升。
如上所述,展开内层循环已经有了显著的加速效果,进一步展开外层循环,不知是否能进一步加速代码,减少运行时间,有待进一步验证。