关于C#:我可以使用cudaMalloc分配比必要数量更多的内存,以避免重新分配吗?

Can I allocate more memory than necessary with cudaMalloc to avoid reallocating?

我正在编写一个代码,使用cuSparse在GPU上用数千个稀疏矩阵进行计算。由于GPU上的内存有限,因此我需要一一对待它们,因为其余的内存将被其他GPU变量和密集矩阵占用。

我的工作流程(使用伪代码)如下:

1
2
3
4
5
6
for (i=0;i<1000;i++){
//allocate sparse matrix using cudaMalloc
//copy sparse matrix from host using cudaMemcpy
//do calculation by calling cuSparse
//deallocate sparse matrix with cudaFree
}

在上面,我在每个步骤中为每个稀疏矩阵分配并释放了内存,因为它们的稀疏性各不相同,因此每个人所需的内存也各不相同。

我是否可以做类似的事情:

1
2
3
4
5
6
7
//allocate buffer once in the beginning using cudaMalloc with some extra space such
//that even the sparse matrix with the highest density would fit.
for (i=0;i<1000;i++){
//copy sparse matrix from host using cudaMemcpy to the same buffer
//do calculation by calling cuSparse
}
//free the buffer once at the end using cudaFree

以上内容避免了每次迭代都必须malloc和释放缓冲区。以上工作有效吗?会提高性能吗?是好的做法还是有更好的方法来做到这一点?


The above avoids having to malloc and free the buffer in each
iteration. Would the above work?

原则上可以。

Would it improve performance?

可能是。内存分配和释放并非没有延迟。

Is it good practice or is there a better way to do this?

一般来说,是的。许多广泛使用的GPU加速框架(例如Tensorflow)使用此策略来降低GPU上的内存管理成本。用例是否有好处,需要您自己进行测试。


tl; dr:是,请预先分配

我会比@talonmies更加直率:

cudaMalloc()cudaFree()非常慢。当您没有其他潜在的GPU内存竞争者时,它们也不是必需的-通过分配尽可能多的预期使用来"全部使用"。然后使用一个子分配器,或用给定的slab初始化的分配器,在其中分配子分配。如果您使用的框架提供了此功能,请使用它;否则,请使用它。否则,请自己编写或寻找可以为您完成的库。