Accelerated Ray Tracing (四)

https://developer.nvidia.com/blog/how-query-device-properties-and-handle-errors-cuda-cc/

在CUDA C/ c++中如何查询设备属性和处理错误

Compute Capability

cudaDeviceProp类型中包含的许多设备属性,特别是major和minor。这些描述了设备的计算能力,这通常在major.minor中给出。并指示第几代架构。

将thread分组为线程block的方式模仿了在GPU上分组线程处理器的方式。这组线程处理器称为流多处理器streaming multiprocessor,在上表中用SM表示。CUDA执行模型在多处理器上执行线程block,一旦执行它们就不会迁移到其他SMs上。受可用资源(on-chip registers和shared memory)和表最后一行所示的限制的限制,多个线程block可以并发驻留在多处理器上。该表中线程和线程块的限制与计算能力相关,而不仅仅是特定的设备:具有相同计算能力的所有设备都有相同的限制。不过,还有其他一些特征,比如每个设备的多处理器数量,这些特征依赖于特定的设备,而不是计算能力。所有这些特征,无论是由特定的设备或其计算能力定义,都可以使用cudaDeviceProp类型获得。

您可以使用nvcc编译器选项-arch=sm_xx为特定的计算能力生成代码,其中xx表示计算能力(没有小数点)。要查看特定版本的nvcc可以为其生成代码的计算能力列表,以及其他与cuda相关的编译器选项,请发出命令nvcc—help并参考-arch条目。

当您为内核指定执行配置时,请记住(并在运行时查询)上表中的限制。这对于第二个执行配置参数(每个线程块的线程数)尤其重要。如果您为每个块指定的线程太少,那么对每个多处理器的线程块的限制将限制可以实现的并行量。如果每个线程块指定了太多线程,那么我们就进入下一节。

Handling CUDA Errors

所有CUDA C Runtime API函数都有一个返回值,可用于检查在执行过程中发生的错误。在上面的示例中,我们可以像下面这样检查cudaGetDeviceCount()是否成功完成:

cudaError_t err = cudaGetDeviceCount(&nDevices);
  if (err != cudaSuccess) printf("%s\n", cudaGetErrorString(err));

Handling kernel errors 有点复杂,因为kernel 相对于host是异步执行的。为了帮助检查kernel 执行的错误,以及其他异步操作,CUDA runtime 维护了一个错误变量,该变量在每次发生错误时都会被覆盖。函数cudaPeekAtLastError()返回该变量的值,函数cudaGetLastError()返回该变量的值并将其重置为cudaSuccess。

saxpy<<<(N+255)/256, 256>>>(N, 2.0, d_x, d_y);
cudaError_t errSync  = cudaGetLastError();
cudaError_t errAsync = cudaDeviceSynchronize();
if (errSync != cudaSuccess) 
  printf("Sync kernel error: %s\n", cudaGetErrorString(errSync);
if (errAsync != cudaSuccess)
  printf("Async kernel error: %s\n", cudaGetErrorString(errAsync);

此代码检查synchronous 和asynchronous 错误。无效的执行配置参数,例如每个线程块有太多的线程,会在cudaGetLastError()返回的errSync值中反映出来。Asynchronous 错误发生在device 控制返回到host后,如内存访问越界,需要一个同步机制,如cudaDeviceSynchronize(),它阻塞主机线程,直到所有之前发出的命令完成。任何异步错误都由cudaDeviceSynchronize()返回。我们还可以检查异步错误,并通过修改最后一条语句调用cudaGetLastError()来重置运行时错误状态。

if (errAsync != cudaSuccess)
  printf("Async kernel error: %s\n", cudaGetErrorString(cudaGetLastError());

Device 同步是昂贵的,因为它会导致整个设备等待,从而破坏程序中此时的任何潜在并发性。所以要小心使用。通常,我只在代码的调试构建中使用预处理器宏来插入异步错误检查,而不是在发布构建中。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值