1.cpu的运算
对于cpu的运算,我们需要遍历3次,如果A*B=C,A为M*K维,B维K*N维,C为M*N为,则我们首先要遍历P的M维和N维,在遍历K维进行计算:
2.gpu运算
对gpu运算,由于是并行运算,C矩阵的每个数值同时计算,我们的思路是每个线程(thread)处理一个矩阵上的数值,所以线程的坐标可以代表矩阵C的坐标,例如对于矩阵C8*8的矩阵:
我们可以让blockdim为4*4,也就是一个block中有16个线程,则2*2的grid就能算完所有C矩阵上的值,具体我们的核函数如下:
下面我们把cpu的数据传入gpu中进行并行运算:
进行试验:
实验参数:
实验我们进行了5组:有cpu,gpu预热,blocksize=16,blocksize=1,blocksize=32。
实验结果:
显然即便是预热的gpu运算也比cpu快,后面几组可以说明一些问题,gpu_blocksize=1运算的速度最慢,因为同一个block(线程块)中的所有thread(线程)共享一块该block专属的 shared memory;而同一个grid(线程格)中的不同block之间,各自的 shared memory 是相互独立、完全隔离的,所以blocksize=1代表着每个线程都不是共享的,算法只能依赖全局内存,访问速度很慢,而为什么blocksize=32变得就很快了呢?且硬件调度无冗余,GPU 以 32 个线程为 1 个 warp 调度,q所以blocksize=32最快。
优化:数据其实一直都是在gobalmemory中取,其实很慢,我们可以创建sharememory来加快速度。