主机循环的 CUDA 布尔变量
CUDA boolean variable for host loop
我的代码的一个非常简化的版本如下所示:
do {
//reset loop variable b to 0/false
b = 0;
// execute kernel
kernel<<<...>>>(b);
// use the value of b for while condition
} while(b);
布尔变量 b
可以由 kernel
中的任何线程设置为 true
,它告诉我们是否继续 运行 循环。
使用 cudaMalloc
、cudaMemset
和 cudaMemcpy
我们可以 create/set/copy device
内存来实现这一点。但是我刚刚发现固定内存的存在。使用 cudaMalloHost
分配 b
并在内核在一个简单的测试程序中提供相当大的加速(~50%)后立即调用 cudaDeviceSynchronize
。
固定内存是这个布尔变量的最佳选择吗b
还是有更好的选择?
您没有显示您的初始代码和 修改后的 代码,因此没有人知道您在 post 中陈述的改进细节。
您问题的答案因
而异
- b读写或只写在GPU内核内部。如果在缓存中找不到 b 导致延迟,读取可能需要直接从主机端获取实际值。另一方面,如果有进一步的操作可以使线程保持忙碌,则可以弥补写入的延迟。
- 您修改值的频率。如果您在程序中频繁访问该值,GPU 可能会将变量保留在 L2 中,避免主机端访问。
- 两次访问 b 之间的内存操作频率。如果对b的访问之间有很多内存事务,则更有可能将缓存中的b替换为其他内容。结果再次访问时,缓存中找不到b,需要耗时的host-access
如果主机端有 b 会导致许多主机内存事务,将其保存在 GPU 全局内存中并在每个循环结束时将其传回是合乎逻辑的迭代。您可以在与内核相同的流中使用异步副本来相当快地完成此操作,然后立即与主机同步。
以上所有项目均适用于启用缓存的设备。如果您的设备是 pr-Fermi (CC<2.0),情况就不同了。
我的代码的一个非常简化的版本如下所示:
do {
//reset loop variable b to 0/false
b = 0;
// execute kernel
kernel<<<...>>>(b);
// use the value of b for while condition
} while(b);
布尔变量 b
可以由 kernel
中的任何线程设置为 true
,它告诉我们是否继续 运行 循环。
使用 cudaMalloc
、cudaMemset
和 cudaMemcpy
我们可以 create/set/copy device
内存来实现这一点。但是我刚刚发现固定内存的存在。使用 cudaMalloHost
分配 b
并在内核在一个简单的测试程序中提供相当大的加速(~50%)后立即调用 cudaDeviceSynchronize
。
固定内存是这个布尔变量的最佳选择吗b
还是有更好的选择?
您没有显示您的初始代码和 修改后的 代码,因此没有人知道您在 post 中陈述的改进细节。
您问题的答案因
而异- b读写或只写在GPU内核内部。如果在缓存中找不到 b 导致延迟,读取可能需要直接从主机端获取实际值。另一方面,如果有进一步的操作可以使线程保持忙碌,则可以弥补写入的延迟。
- 您修改值的频率。如果您在程序中频繁访问该值,GPU 可能会将变量保留在 L2 中,避免主机端访问。
- 两次访问 b 之间的内存操作频率。如果对b的访问之间有很多内存事务,则更有可能将缓存中的b替换为其他内容。结果再次访问时,缓存中找不到b,需要耗时的host-access
如果主机端有 b 会导致许多主机内存事务,将其保存在 GPU 全局内存中并在每个循环结束时将其传回是合乎逻辑的迭代。您可以在与内核相同的流中使用异步副本来相当快地完成此操作,然后立即与主机同步。
以上所有项目均适用于启用缓存的设备。如果您的设备是 pr-Fermi (CC<2.0),情况就不同了。