使用各种方法加速大型矩阵运算的效率对比

     并行程序设计这门课程的课程实验要求我分别使用串行, 并行+分块算法, 并行+分块+SSE指令集加速, CUDA等四种方法来计算矩阵乘法.

     还真别说收获蛮大的.

     我的配置是i5 3470+GTX660Ti

     下面的表格是各种算法下的情况.

矩阵规模 串行 多线程+分块 多线程+分块+SSE CUDA
512 572.2(ms) 169.7(ms) 21.8(ms) 351.5(ms)
1024 11295.9(ms) 1367.1(ms) 134.5(ms) 395.5(ms)
2048 142193.0(ms) 10445.7(ms) 1118.3(ms) 1051.4(ms)
4096 1213014.6(ms) 81608.3(ms) 8737.2(ms) 6197.3(ms)

     从图中明显可以看出, 这个分块之后cache利用效率大大提高,本来如果普通多线程相对于串行来说不过 4倍,但是这里速度达到了10倍多. 也就是说CPU Cache的合理利用非常有用.

     SSE的加速效果就非常厉害了, 相对于分块又提高了10倍的速度.不过 SSE的浮点数运算准确度好低啊!!!!! 误差超级大. 但是矩阵的每个点误差又只有1点几. 但是每个点都有1点几, 结果矩阵的所有点的误差之和就看起来简直不堪入目.

     CUDA的效果简直非常拔群. 而且时间还包括了传输数据到显卡的时间.

    

     哦,说些闲话. 

     CUDA的设备变量的地址是分配在操作系统的kernel层的,直接访问会导致memory access violate错误. 

     比如

    

     Matrix A{ int w;int h; float *d;};

     Matrix * A;

     cudaMalloc((void**)&A,sizeof(Matrix));

     A->w = 16;   //这里会出错.!!!


      还有,在运行CUDA程序时, Win 8 会有显卡超时设置,如果你的CUDA程序时间运行太久,显卡会失去响应,然后windows就自动对显卡重置. 你的屏幕右下角会出现说,显卡驱动已停止响应,自动恢复的错误. 你的CUDA程序会返回编号为30的UnkownError类型.

      需要在注册表里 设置 关闭windows TDR 或者加长延时上限.

具体参考

http://stackoverflow.com/questions/13177214/disabling-tdr-for-cuda-in-windows-8

http://msdn.microsoft.com/en-us/Library/Windows/Hardware/ff569918(v=vs.85).aspx

 

代码地址 https://files.cnblogs.com/tlm1992/matrix_product.zip

    

 

posted @ 2014-04-07 15:32  写程序的⑨  阅读(5070)  评论(0编辑  收藏  举报