【问题标题】:CUDA error when handling large input处理大输入时出现 CUDA 错误
【发布时间】:2013-06-06 11:54:35
【问题描述】:

所以我发生了一个相当奇怪的错误。我有一个内核,它应该改变数组中每个元素的值。截至目前,我只测试启动一个线程。

    __global__ void kernel(int* data) {
        for (int var = 0; var < SIZE; ++var) {
            data[var] = data[var] + 1;
        }
    }

这是整个代码:

    #include "stdint.h"
    #include "stdio.h"
    #include "kernelLauncher.cuh"
    #include <cuda_runtime.h>

    #define  SIZE 10485760

    typedef uint64_t POLY_64;
    typedef unsigned char BYTE;


    __global__ void kernel(int* data) {

        for (int var = 0; var < SIZE; ++var) {
            data[var] = data[var] + 1;
        }

    }

    int main() {

        int* data = (int*) malloc(sizeof(int) * SIZE);
        int* data_d;

        for (int var = 0; var < SIZE; ++var) {
            data[var] = 1;
        }
        //allocate device memory for the fingerprinting data
        cudaMalloc((void**) &data_d, sizeof(int) * SIZE);

        //copy the data to device

        CUDA_CHECK_RETURN(
                cudaMemcpy(data_d, data, sizeof(int) * SIZE, cudaMemcpyHostToDevice));

        kernel<<<1, 1>>>(data_d);
        cudaThreadSynchronize();


        CUDA_CHECK_RETURN(cudaMemcpy(data, data_d, sizeof(int) * SIZE, cudaMemcpyDeviceToHost));

        //try to print the result
        for (int var = 0; var < SIZE; ++var) {
            printf("%d\n", data[var]);
        }

        CUDA_CHECK_RETURN(cudaFree(data_d));
        return 0;
    }

当我的 SIZE 定义为 1048576 时,我的数据恢复得很好。不幸的是,当我将其定义为 10485760(10 倍以上)时。我明白了:

    Error unspecified launch failure at line 40 in file ../src/runTest.cu

谁能指出我正确的方向。为什么会出现这个问题?提前谢谢你

编辑:所以是的.. 这是尺寸定义。我现在更改了我的代码,因此内核中的硬编码循环值和定义的常量之间没有差异。但是,如果我有 10485760 而不是 1048576 它根本不起作用.. 为什么会这样。一口气分配的不算多。。我的卡是计算能力1.1的Quadro FX 770m

【问题讨论】:

  • 第 89 行是哪一行?为什么不对所有 API 调用和内核启动进行错误检查。如果不知道错误出现在代码的哪个位置,很难给出答案....
  • 真的很抱歉。谈到 CUDA,我是一个真正的菜鸟。错误的行实际上不在发布的源代码中。该行是将结果复制回主机的行: CUDA_CHECK_RETURN(cudaMemcpy(data, data_d, sizeof(int) * SIZE, cudaMemcpyDeviceToHost));话虽如此..问题可能是我没有与 cudaThreadSynchronize() 同步;在我启动内核之后,在我尝试将数据复制回来之前?
  • 我已经更新了我的代码,以便更好地反映正在发生的事情。
  • 内核呢? 1048576 是真的在循环中硬编码,还是实际上是SIZE?如果您希望我们准确地告诉您出了什么问题,您必须向我们展示准确代码。否则我们怎么可能说问题是什么? (几乎可以肯定它就像你想象的那样)
  • 所以现在代码看起来在SIZE=10485760 时应该可以正常工作,而在SIZE=1048576 时不能正常工作,即。与您告诉我们的相反。我这么说是因为SIZE=1048576 的情况应该是内核中保证的越界内存错误。

标签: c++ c cuda parallel-processing nvidia


【解决方案1】:

所以.. 这就是实际发生的事情。正如你们中的一些人所建议的那样,内核确实花费了太长时间并且超时(尽管我从各种来源中了解到这在 Linux 系统上不会发生)所以像这样分离工作实际上解决了问题并避免了看门狗杀死内核:

        kernel<<<1, 1>>>(data_d, 0, 1048576);
        cudaDeviceSynchronize();
        kernel<<<1, 1>>>(data_d, 1048576, 2097152);
        cudaDeviceSynchronize();
        kernel<<<1, 1>>>(data_d, 2097152, 3145728);
        cudaDeviceSynchronize();
        kernel<<<1, 1>>>(data_d, 3145728, 4194304);
        cudaDeviceSynchronize();
        kernel<<<1, 1>>>(data_d, 4194304, 5242880);
        cudaDeviceSynchronize();
        kernel<<<1, 1>>>(data_d, 5242880, 6291456);
        cudaDeviceSynchronize();
        kernel<<<1, 1>>>(data_d, 6291456, 7340032);
        cudaDeviceSynchronize();
        kernel<<<1, 1>>>(data_d, 7340032, 8388608);
        cudaDeviceSynchronize();

现在我想知道,避免达到这个阈值的方法是什么。我尝试添加

    Section "Device"
        Identifier     "Device0"
        Driver         "nvidia"
        VendorName     "NVIDIA Corporation"
        Option         "Interactive" "0"  #<<--- added to avoid kernel time-out
    EndSection

进入我的 Xorg.conf 中的设备部分,但这并没有真正帮助。

【讨论】:

  • Linux 还为托管 X 显示器的 GPU 提供了一些看门狗机制。 This document 可能感兴趣。我认为您想将“交互式”参数设置为“关闭”而不是“0”,但请检查您的驱动程序发行说明以确认正确的设置。
  • 您可以使用 Nsight 监视器在常规选项卡中更改 Windows 上的超时。以下页面解释更多developer.download.nvidia.com/NsightVisualStudio/2.2/…
猜你喜欢
  • 2016-08-20
  • 1970-01-01
  • 2011-12-08
  • 1970-01-01
  • 2019-05-11
  • 1970-01-01
  • 1970-01-01
  • 2017-09-05
  • 1970-01-01
相关资源
最近更新 更多