Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 表观库达魔法_C++_C_Cuda_Pycuda - Fatal编程技术网

C++ 表观库达魔法

C++ 表观库达魔法,c++,c,cuda,pycuda,C++,C,Cuda,Pycuda,我正在使用CUDA(实际上,如果差异很重要的话,我正在使用pyCUDA)并在数组上执行一些计算。我正在启动一个包含320*600个线程的网格内核。在内核中,我声明了两个由20000个组件组成的线性阵列,使用: float test[20000] float test2[20000] 使用这些数组,我执行简单的计算,比如用常量值填充它们。关键是内核正常执行,并且正确执行计算(您可以看到,用随机测试组件填充一个数组,并将该数组从设备发送到主机) 问题是,我的NVIDIA卡只有2GB内存,用于分配阵

我正在使用CUDA(实际上,如果差异很重要的话,我正在使用pyCUDA)并在数组上执行一些计算。我正在启动一个包含320*600个线程的网格内核。在内核中,我声明了两个由20000个组件组成的线性阵列,使用:

float test[20000]
float test2[20000]
使用这些数组,我执行简单的计算,比如用常量值填充它们。关键是内核正常执行,并且正确执行计算(您可以看到,用随机测试组件填充一个数组,并将该数组从设备发送到主机)

问题是,我的NVIDIA卡只有2GB内存,用于分配阵列测试和测试2的内存总量为320*600*20000*4字节,远远超过2GB

这段记忆是从哪里来的?CUDA如何在每个线程中执行计算?


感谢您的时间

本地/堆栈内存需求的实际大小并不像您想象的那样(对于整个网格,一次完成),而是基于@njuffa描述的公式

基本上,本地/堆栈内存需求的大小是基于正在运行的设备的最大瞬时容量,而不是网格的大小

根据njuffa提供的信息,可用堆栈大小限制(每个线程)为以下较小值:

  • 最大本地内存大小(cc2.x及更高版本为512KB)
  • 可用GPU内存/(#个SMs)/(每个SM的最大线程数)
  • 对于您的第一个案例:

    float test[20000];
    float test2[20000];
    
    这个总数是160KB(每个线程),所以我们在每个线程512KB的最大限制之下。第二个限制呢

    有2个cc 3.0(开普勒)SMs(每个开普勒SM有192个内核)。因此,如果所有GPU内存可用,上述第二个限制给出:

    2GB/2/2048=512KB

    (开普勒有) 所以在这种情况下,它是相同的极限。但这假设所有GPU内存都可用

    由于您在评论中建议此配置失败:

    float test[40000];
    float test2[40000];
    
    i、 e.320KB,我可以得出结论,您的实际可用GPU内存处于此批量分配尝试的点上,高于(160/512)*100%,即高于31%,但低于(320/512)*100%,即低于2GB的62.5%,因此,我可以得出结论,在堆栈帧的批量分配请求时,您的可用GPU内存将小于1.25GB

    您可以在相关内核启动之前调用
    cudaGetMemInfo
    (尽管我不知道如何在pycuda中实现这一点),来尝试查看情况是否如此。即使你的GPU一开始是2GB,如果你用它来运行显示器,你很可能会从一个接近1.5GB的数字开始。在内核启动时,在此批量分配请求之前发生的动态(例如
    cudamaloc
    )和/或静态(例如
    \uuuuuu设备\uuuuuu
    )分配都会影响可用内存


    这些都是为了解释一些细节。对您的问题的一般回答是,之所以会出现“魔力”,是因为GPU不一定同时为网格中的所有线程分配堆栈帧和本地内存。它只需分配设备的最大瞬时容量所需的容量(即SMs*每个SM的最大线程数),这可能是一个明显小于整个网格所需容量的数字。

    本地/堆栈内存需求的实际大小与您想象的不同(对于整个网格,一次完成)但实际上是基于@njuffa描述的公式

    基本上,本地/堆栈内存需求的大小是基于正在运行的设备的最大瞬时容量,而不是网格的大小

    根据njuffa提供的信息,可用堆栈大小限制(每个线程)为以下较小值:

  • 最大本地内存大小(cc2.x及更高版本为512KB)
  • 可用GPU内存/(#个SMs)/(每个SM的最大线程数)
  • 对于您的第一个案例:

    float test[20000];
    float test2[20000];
    
    这个总数是160KB(每个线程),所以我们在每个线程512KB的最大限制之下。第二个限制呢

    有2个cc 3.0(开普勒)SMs(每个开普勒SM有192个内核)。因此,如果所有GPU内存可用,上述第二个限制给出:

    2GB/2/2048=512KB

    (开普勒有) 所以在这种情况下,它是相同的极限。但这假设所有GPU内存都可用

    由于您在评论中建议此配置失败:

    float test[40000];
    float test2[40000];
    
    i、 e.320KB,我可以得出结论,您的实际可用GPU内存处于此批量分配尝试的点上,高于(160/512)*100%,即高于31%,但低于(320/512)*100%,即低于2GB的62.5%,因此,我可以得出结论,在堆栈帧的批量分配请求时,您的可用GPU内存将小于1.25GB

    您可以在相关内核启动之前调用
    cudaGetMemInfo
    (尽管我不知道如何在pycuda中实现这一点),来尝试查看情况是否如此。即使你的GPU一开始是2GB,如果你用它来运行显示器,你很可能会从一个接近1.5GB的数字开始。在内核启动时,在此批量分配请求之前发生的动态(例如
    cudamaloc
    )和/或静态(例如
    \uuuuuu设备\uuuuuu
    )分配都会影响可用内存


    这些都是为了解释一些细节。对您的问题的一般回答是,之所以会出现“魔力”,是因为GPU不一定同时为网格中的所有线程分配堆栈帧和本地内存。它只需分配设备的最大瞬时容量所需的容量(即SMs*每个SM的最大线程数),这可能是一个明显小于整个网格所需容量的数字。

    要完整回答此问题,需要知道您运行的实际GPU。这个