我有一个#pragma unroll 80
的内核,我用NVIDIA GT 285运行它,计算能力1.3,
使用网格架构:dim3 thread_block( 16, 16 )
和dim3 grid( 40 , 30 )
,它可以正常工作。
当我尝试使用NVIDIA GT 580,计算能力2.0并使用上述网格架构时,它运行正常。
当我将GT 580上的网格架构更改为
时 dim3 thread_block( 32 , 32 )
和dim3 grid( 20 , 15 )
,因此产生与上面相同数量的线程,我得到的结果不正确。
如果我在GT 580中移除#pragma unroll 80
或将其替换为#pragma unroll 1
,则可以正常使用。如果我没有,那么内核崩溃。
有谁知道为什么会这样?提前谢谢
编辑:检查两台设备上的内核错误,我收到了“无效参数”。 当我搜索这个错误的原因时,我发现当网格和块的尺寸超出其限制时会发生这种情况。 但对我来说情况并非如此,因为我每块使用16x16 = 256个线程,而40x30 = 1200个总块。据我所知,这些值位于GPU网格的边界内,用于计算能力1.3。 我想知道这是否与我的循环展开问题有关。
答案 0 :(得分:1)
我弄清楚问题是什么。
在修复了一些错误之后,我收到了“请求启动的资源过多”错误。 对于循环展开,需要每个线程额外的寄存器,并且我的寄存器用完了,因此错误和内核失败。 我每个线程需要22个寄存器,每个块有1024个线程。
通过将我的数据插入到CUDA_Occupancy_calculator中,它向我展示了每个SM的1个块被调度,留下了32678个寄存器,用于计算能力2.0设备上的整个块。
22个寄存器* 1024个线程= 22528个寄存器< 32678应该有效。 但我正在使用C.C.编译nvcc -arch sm_13。 1.3每个SM的16384个寄存器的特性
我使用nvcc -arch sm_20编译利用32678寄存器,足以满足所需的22528,现在它工作正常。 感谢大家,我了解了内核错误。