我正在一个对三角形数据执行并行处理的组项目中。该程序与外部API接口,可以添加新多边形,删除它们或更新转换矩阵(类似于图形引擎的工作方式)。我们启动了一系列执行处理的内核。但是,没有内核本身修改输入三角形数据。初始化单独的存储器组并用于输出。主机访问此内存块。
此外,与运行循环的迭代次数相比,我们不希望经常更新三角形数据。目前,我们不使用CUDA的统一内存功能,我们的所有内存都是手动分配并使用cudaMalloc
& cudaFree
。
我们正在讨论是否要迁移到统一内存模型并将内存分配为托管内存。但是,我们不确定它将如何影响我们的运行时间。
概述,这就是我们目前的处理方式:
Triangle * tris;
cudaMalloc(&tris, numTris * sizeof(tris)); // <--considering changing this to cudaMallocManaged.
DataOut * dataOut;
cudaMalloc(&dataOut, numTris * sizeof(DataOut)); // <--considering changing this to cudaMallocManaged.
// Copy triangle data here.
while(!quit) {
if(update) {
// If triangles added/removed, memory is reallocated and filled here by the host.
}
kernel1<<<numBlocks, blockSize>>>(tris, dataOut);
kernel2<<<numBlocks, blockSize>>>(tris, dataOut);
//etc...
cudaDeviceSynchronize();
//Now we copy the output data back to host for further processing.
}
cudaFree(triangles);
cudaFree(dataOut);
我认为,与我们当前的实现相比,更改使用统一内存不会产生性能损失,因为我们的内核从不修改三角形数据,并且主机在内核执行时永远不会访问三角形或输出数据数组。即使主机访问输出数据,我们当前也会手动将其复制回来。我的同事认为,UM系统会在每次执行内核之前将三角形数据复制回设备,无论主机是否已经访问过它,从而导致显着的运行时间损失。这是真的?分配托管内存时,可以指示我们更喜欢数据驻留的实体(在我们的例子中是GPU)吗?