我认为CUBLAS可能是单个大型矩阵乘法或加法等的有效算法包。但在通用设置中,大多数计算都是相关的。所以下一步依赖于上一步的结果。
这会导致一个问题,因为输出矩阵必须与CUBLAS例程中的输入矩阵不同(因为输入矩阵是const),花费很多时间用于malloc空间并将数据从设备复制到设备以用于这些临时矩阵。 / p>
那么可以做一些事情,比如乘法(A,A,B),其中第一个参数是输出矩阵,第二个/第三个是输入矩阵,以避免额外的内存操作时间?或者有更好的解决方法吗?
非常感谢!
答案 0 :(得分:4)
不可以使用CUBLAS执行gemm
之类的就地操作(事实上,我不知道任何并行的BLAS实现可以保证这样的操作可行)。
话虽如此,这条评论:
....花费很多时间花在malloc空间上并将数据从设备复制到这些临时矩阵的设备。
让我觉得你可能会忽略那些显而易见的事情。虽然有必要为临时矩阵分配空间,但在使用此类分配时,当然不必执行设备到设备的内存副本。这样:
// If A, B & C are pointers to allocations in device memory
// compute C = A*B and copy result to A
multiply(C, A, B);
cudaMemcpy(A, C, sizeA, cudaMemcpyDeviceToDevice);
// now A = A*B
可以替换为
multiply(C, A, B);
float * tmp = A; A = C; C = tmp;
即。你只需要在主机上交换指针来执行相当于设备到设备内存的复制,但没有GPU时间成本。这不能在任何情况下使用(例如,有一些就地块操作可能仍然需要显式内存传输),但在大多数情况下,可以避免显式设备到设备内存传输。
如果使用CUBLAS进行大型密集操作的内存成本限制了您的应用程序,请考虑调查"out of core" approaches以使用大型密集矩阵。
答案 1 :(得分:1)
您可以预先分配缓冲区矩阵,并在mat-mul操作之前将输入矩阵A复制到缓冲区。
Memcopy(buff, A);
Multiply(A, buffer, B);
通过重用缓冲区,您不需要每次都分配缓冲区,并且每个mat-mul的开销只有一个mem副本。当矩阵足够大时,开销的时间成本将占很小的一部分,可以忽略。