超时后,启动在cudaDeviceSynchronize中终止

时间:2014-07-19 12:57:07

标签: cuda gpu-programming

我尝试使用3维网格运行一个简单的程序,但由于某种原因,当我使用cuda-memcheck启动它时它会卡住,并且在超时后它终止。这个问题与短暂的超时无关,因为我将这种方式改为60秒。

我运行的代码有一个45x1575x1575的网格,它运行一个空的__global__函数。我的计算能力是2.1,我使用标志-maxrregcount=24进行编译,以限制设备功能可以使用的寄存器数量(在我的其他程序中看到它使用占用计算器可以获得最佳结果)

这是我的代码:

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>

__global__ void stam(int a){

}

int main()
{


    // Choose which GPU to run on, change this on a multi-GPU system.
    cudaError_t cudaStatus = cudaSetDevice(0);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU installed?");
        return;
    }

    dim3 gridSize(45,1575,1575);
    stam<<<gridSize,224>>>(4);
    cudaStatus = cudaDeviceSynchronize(); // This function gets stuck
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaSetDevice failed!!");
        return;
    }

    cudaStatus = cudaDeviceReset();
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaDeviceReset failed!");
        return 1;
    }

    return 0;
}

最大网格尺寸是否为65535x65535x65535?这里有什么问题?

编辑:当我用-G标志编译时它只会崩溃。否则它只是很慢,但它不会超过60秒。

2 个答案:

答案 0 :(得分:2)

您的代码运行时间过长(是的,超过60秒)。

即使您的内核“什么都不做”,它仍然代表__global__函数调用。为方便起见,编译器会生成大量的前导码。通常,编译器会优化大部分前导码,因为你的函数什么都不做(例如,它对传递给它的变量没有任何作用,前导码代码可以为每个线程提供。)但是当你传递-G时切换,您几乎消除了所有编译器优化。通过将可执行文件和inspecting the codecuobjdump -sass ...一起使用,您可以了解每个线程块实际运行的代码的大小。

其次,使用cuda-memcheck运行代码通常会增加执行时间。 cuda-memcheck执行程序调整顺序并降低执行线程块的速率,因此它可以对每个线程块的内存访问模式进行全面分析,等等。

净效应是你的空内核调用,部分是由于非常大的网格(需要处理超过1亿个线程块),执行时间超过60秒。如果要验证这一点,请将TDR超时时间增加到5分钟或10分钟,最终您将看到程序正常返回。

在我的情况下,使用-Gcuda-memcheck,您的程序需要大约30秒才能在拥有11个SM的Quadro5000 GPU上运行。你的cc2.1 GPU可能有大约2个SM,因此比我的运行速度更慢。如果我在没有-G开关的情况下编译,则运行时间会下降到大约2秒。如果我使用-G开关进行编译,但在没有cuda-memcheck的情况下运行,则大约需要4秒钟。如果我从内核中消除了int a参数(这大大减少了前导代码),我可以使用-G进行编译并使用cuda-memcheck运行,只需要2秒。

包含-Gint a参数的内核机器代码:

            Function : _Z4stami
    .headerflags    @"EF_CUDA_SM20 EF_CUDA_PTX_SM(EF_CUDA_SM20)"
    /*0000*/         MOV R1, c[0x1][0x100];            /* 0x2800440400005de4 */
    /*0008*/         ISUB R1, R1, 0x8;                 /* 0x4800c00020105d03 */
    /*0010*/         S2R R0, SR_LMEMHIOFF;             /* 0x2c000000dc001c04 */
    /*0018*/         ISETP.GE.AND P0, PT, R1, R0, PT;  /* 0x1b0e00000011dc23 */
    /*0020*/     @P0 BRA 0x30;                         /* 0x40000000200001e7 */
    /*0028*/         BPT.TRAP;                         /* 0xd00000000000c007 */
    /*0030*/         IADD R0, R1, RZ;                  /* 0x48000000fc101c03 */
    /*0038*/         MOV R2, R0;                       /* 0x2800000000009de4 */
    /*0040*/         MOV R3, RZ;                       /* 0x28000000fc00dde4 */
    /*0048*/         MOV R2, R2;                       /* 0x2800000008009de4 */
    /*0050*/         MOV R3, R3;                       /* 0x280000000c00dde4 */
    /*0058*/         MOV R4, c[0x0][0x4];              /* 0x2800400010011de4 */
    /*0060*/         MOV R5, RZ;                       /* 0x28000000fc015de4 */
    /*0068*/         IADD R2.CC, R2, R4;               /* 0x4801000010209c03 */
    /*0070*/         IADD.X R3, R3, R5;                /* 0x480000001430dc43 */
    /*0078*/         MOV32I R0, 0x20;                  /* 0x1800000080001de2 */
    /*0080*/         LDC R0, c[0x0][R0];               /* 0x1400000000001c86 */
    /*0088*/         IADD R2.CC, R2, RZ;               /* 0x48010000fc209c03 */
    /*0090*/         IADD.X R3, R3, RZ;                /* 0x48000000fc30dc43 */
    /*0098*/         MOV R2, R2;                       /* 0x2800000008009de4 */
    /*00a0*/         MOV R3, R3;                       /* 0x280000000c00dde4 */
    /*00a8*/         ST.E [R2], R0;                    /* 0x9400000000201c85 */
    /*00b0*/         BRA 0xc8;                         /* 0x4000000040001de7 */
    /*00b8*/         EXIT;                             /* 0x8000000000001de7 */
    /*00c0*/         EXIT;                             /* 0x8000000000001de7 */
    /*00c8*/         EXIT;                             /* 0x8000000000001de7 */
    /*00d0*/         EXIT;                             /* 0x8000000000001de7 */
            .........................

包含-G但没有int a参数的内核机器代码:

            Function : _Z4stamv
    .headerflags    @"EF_CUDA_SM20 EF_CUDA_PTX_SM(EF_CUDA_SM20)"
    /*0000*/         MOV R1, c[0x1][0x100];  /* 0x2800440400005de4 */
    /*0008*/         BRA 0x20;               /* 0x4000000040001de7 */
    /*0010*/         EXIT;                   /* 0x8000000000001de7 */
    /*0018*/         EXIT;                   /* 0x8000000000001de7 */
    /*0020*/         EXIT;                   /* 0x8000000000001de7 */
    /*0028*/         EXIT;                   /* 0x8000000000001de7 */
            .........................

答案 1 :(得分:0)

我只是在cuda-memcheck和cuda-gdb下的C2050(功能2.0)上运行你的代码没有任何问题。这表明问题更可能与您的卡/设置有关,而不是代码本身。

如果您超出了功能,则应该获得启动错误代码,而不是挂起(如果您不确定,可以使用deviceQuery SDK代码检查最大尺寸)。

可能是cuda-memcheck试图获得对GPU的独占控制,并且正在使用其他东西进行超时[例如您的X服务器] - cuda-gdb是否更好用,这些工​​具是否适用于其他代码?