C++ 表观库达魔法
我正在使用CUDA(实际上,如果差异很重要的话,我正在使用pyCUDA)并在数组上执行一些计算。我正在启动一个包含320*600个线程的网格内核。在内核中,我声明了两个由20000个组件组成的线性阵列,使用:C++ 表观库达魔法,c++,c,cuda,pycuda,C++,C,Cuda,Pycuda,我正在使用CUDA(实际上,如果差异很重要的话,我正在使用pyCUDA)并在数组上执行一些计算。我正在启动一个包含320*600个线程的网格内核。在内核中,我声明了两个由20000个组件组成的线性阵列,使用: float test[20000] float test2[20000] 使用这些数组,我执行简单的计算,比如用常量值填充它们。关键是内核正常执行,并且正确执行计算(您可以看到,用随机测试组件填充一个数组,并将该数组从设备发送到主机) 问题是,我的NVIDIA卡只有2GB内存,用于分配阵
float test[20000]
float test2[20000]
使用这些数组,我执行简单的计算,比如用常量值填充它们。关键是内核正常执行,并且正确执行计算(您可以看到,用随机测试组件填充一个数组,并将该数组从设备发送到主机)
问题是,我的NVIDIA卡只有2GB内存,用于分配阵列测试和测试2的内存总量为320*600*20000*4字节,远远超过2GB
这段记忆是从哪里来的?CUDA如何在每个线程中执行计算?
感谢您的时间本地/堆栈内存需求的实际大小并不像您想象的那样(对于整个网格,一次完成),而是基于@njuffa描述的公式 基本上,本地/堆栈内存需求的大小是基于正在运行的设备的最大瞬时容量,而不是网格的大小 根据njuffa提供的信息,可用堆栈大小限制(每个线程)为以下较小值:
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提供的信息,可用堆栈大小限制(每个线程)为以下较小值:
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。这个