cuda异常后的记忆数据状态

时间:2015-07-26 22:20:12

标签: exception-handling cuda cuda-gdb

CUDA文档不清楚CUDA应用程序抛出异常后内存数据如何变化。

例如,内核启动(动态)遇到异常(例如Warp超出范围的地址),将停止当前的内核启动。在此之后,设备上的数据(例如__device__变量)是否仍会保留,或者它们是否会被删除?

一个具体的例子是这样的:

  1. CPU启动内核
  2. 内核将__device__ variableA的值更新为5,然后崩溃
  3. CPU memcpy从设备到主机的variableA的值,在这种情况下CPU获得的值是5,还是其他什么?
  4. 有人能说明这背后的理由吗?

1 个答案:

答案 0 :(得分:5)

如果发生CUDA错误会破坏CUDA上下文,则行为未定义。

这种类型的错误是显而易见的,因为它是" sticky",这意味着一旦发生,每个CUDA API调用都将返回该错误,直到上下文被销毁。

非粘性错误在cuda API调用返回后自动清除(cudaPeekAtLastError除外)。任何"崩溃的内核"类型错误(无效访问,未指定的启动失败等)将是一个棘手的错误。在您的示例中,步骤3将(始终)对cudaMemcpy调用的结果返回API错误,以便将variableA从设备传输到主机,因此cudaMemcpy操作的结果未定义且不可靠 - 就好像cudaMemcpy操作也以某种未指定的方式失败了。

由于未定义损坏的CUDA上下文的行为,因此没有任何分配内容的定义,或者通常是在发生此类错误后的机器状态。

非粘性错误的一个示例可能是尝试cudaMalloc多于设备内存中可用的数据。此类操作将返回内存不足错误,但该错误将在返回后被清除,并且后续(有效)cuda API调用可以成功完成,而不会返回错误。非粘性错误不会破坏CUDA上下文,并且cuda上下文的行为与从未请求过无效操作的行为完全相同。

许多记录错误代码descriptions中都会出现粘性和非粘性错误之间的区别,例如:

非粘性,非cuda-context-corrupting:

  

cudaErrorMemoryAllocation = 2   API调用失败,因为它无法分配足够的内存来执行请求的操作。

粘性,cuda-context-corrupting:

  

cudaErrorMisalignedAddress = 74   设备在未对齐的内存地址上遇到加载或存储指令。不能使用上下文,因此必须销毁它(并且应该创建一个新的上下文)。此上下文中的所有现有设备内存分配均无效,如果程序要继续使用CUDA,则必须重新构建。

请注意,cudaDeviceReset()本身不足以将GPU恢复到正常的功能行为。为了实现这一点,"拥有"进程也必须终止。见here