CUDA凸壳程序在大输入时崩溃

CUDA Convex Hull program crashes on large input

本文关键字:输入 崩溃 程序 CUDA      更新时间:2023-10-16

我正试图在CUDA中并行实现快速船体算法(用于凸船体)。对于input_size <= 100万,它可以正确工作。当我尝试1000万点时,程序崩溃了。我的显卡大小为1982 MB,算法中的所有数据结构总共需要的输入大小不超过600 MB,不到可用空间的50%。

通过注释掉我的内核行,我发现当我试图访问数组元素和我试图访问的元素的索引不越界时发生崩溃(双重检查)。下面是它崩溃的内核代码。

for(unsigned int i = old_setIndex; i < old_setIndex + old_setS[tid]; i++) 
{
    int pI = old_set[i];
    if(pI <= -1 || pI > pts.size())
    {               
        printf("Thread %d: i = %d, pI = %dn", tid, i, pI);
        continue;
    }
    p = pts[pI];
    double d = distance(A,B,p);
    if(d > dist) {
        dist = d;
        furthestPoint = i;
        fpi = pI;
    }
}
//fpi = old_set[furthestPoint]; 
//printf("Thread %d: Furthestpoint = %dn", tid, furthestPoint);

当我在for循环后取消注释语句(数组访问和printf)时,我的代码崩溃了。我无法解释这个错误,因为furthestPoint总是在old_set数组大小的范围内。Old_setS存储每个线程可以操作的较小数组的大小。即使只是尝试打印furthestPoint(最后一行)的值,而上面没有数组访问语句,它也会崩溃。

对于输入大小<= 100万,上面的代码没有问题。在1000万的情况下,我是否溢出了设备中的缓冲区?

请帮我找一下崩溃的原因

您的代码中没有越界内存访问(或者至少没有导致您所看到的症状的内存访问)。

正在发生的事情是你的内核被显示驱动程序杀死,因为它在你的显示GPU上执行的时间太多了。所有CUDA平台显示驱动程序都包括GPU上任何操作的时间限制。这是为了防止显示冻结太长时间,导致操作系统内核恐慌或用户恐慌,并认为机器已经崩溃。在您正在使用的windows平台上,时间限制约为2秒。

是什么部分误导你认为问题的根源是数组寻址是代码的注释使问题消失。但真正发生的是编译器优化的产物。当你注释掉一个全局内存写入时,编译器会识别出导致存储值的计算是未使用的,它会从它发出的汇编代码中删除所有这些代码(谷歌"nvcc死代码移除"了解更多信息)。这样做的效果是使代码运行得更快,并将其置于显示驱动程序的时间限制之下。

有关解决方法,请参阅最近的stackoverflow问题和答案