Memory CUDA:被CUDA内存模型和内存分配搞糊涂了

Memory CUDA:被CUDA内存模型和内存分配搞糊涂了,memory,cuda,Memory,Cuda,对于任何像我在未来一样困惑的人,TLDR: Malloc(从CPU线程调用时)在主机上分配内存。你已经知道了,这里没什么不同 Malloc(当从GPGPU[device]线程调用时)在设备上分配内存或GPGPU内存。这基本上就是在CUDA内核中分配内存所需要的 Cudamaloc有点奇怪,因为它在设备上分配内存,但从主机函数调用(比如int main())。因此,这是从CPU上执行的线程调用的,但在设备或GPGPU上分配内存。我还不完全理解发生这种情况时指针指向什么 问题: 我是CUD

对于任何像我在未来一样困惑的人,TLDR:

  • Malloc(从CPU线程调用时)在主机上分配内存。你已经知道了,这里没什么不同

  • Malloc(当从GPGPU[device]线程调用时)在设备上分配内存或GPGPU内存。这基本上就是在CUDA内核中分配内存所需要的

  • Cudamaloc有点奇怪,因为它在设备上分配内存,但从主机函数调用(比如int main())。因此,这是从CPU上执行的线程调用的,但在设备或GPGPU上分配内存。我还不完全理解发生这种情况时指针指向什么

问题: 我是CUDA的新手。我目前对CUDA中内存分配的工作方式感到困惑

为了深入理解,我可以问很多问题,但为了简单起见,我只想问1个问题

我正在并行化一段代码,这段代码是我为使用C++11线程而编写的。(实际上,它已经并行化了,我只是从CPU线程转移到GPU线程。)

我有一个cuda内核函数。看起来是这样的:

__global__
void cuda_kernel(int N)
{
    std::vector<double> vec;
    for(int i = 0; i < N; ++ i) vec.push_back(0.0);
}
\u全局__
void cuda_内核(int N)
{
std::vec;
对于(int i=0;i
然而,这是不允许的


旁注:

我不知道为什么。我也不在乎为什么,但如果你愿意告诉我,我很乐意阅读你提供的信息。知道原因总是好的,但这不是我的主要问题。(我经常会遇到这样的问题,有人回答了他们想看的问题,而不是实际提出的问题,所以这就是我提出这一评论的原因。请“阅读完整的问题”是我高中数学老师经常说的话!但你可能并不在意。)

请注意,有些人似乎对包含此代码的原因感到困惑。这只是为了证明我意识到我不能这么做。我最初编写的代码是“代码> STD::向量< /代码>,但现在我意识到它不能在CUDA系统上工作,我不再使用C++和向量,我使用C和(希望我能更好地理解)“老校派”的内存分配——我现在相信它包含<代码> CUDAMLARCULE()/<代码>或<代码> MARROCK()。
-但对于使用哪一个,存在着困惑


回到问题上来 我不知道如何在CUDA内核函数/运行在CUDA GPGPU设备上的线程中使用动态内存。这是我想知道的:

我怎么

  • 在GPGPU设备上分配内存供GPGPU使用
  • 在我使用完此内存后释放/释放它
  • 访问此内存的读/写操作
不要担心数据竞争,因为。。。 (这是一个类似的过程,解释了原因。)

我的并行化进程就是我所说的本质上并行化或平凡的可并行化进程。我不可能获得数据竞争/内存损坏,因为所有内存块都独立于其他所有块。可以将其视为类似于向量加法问题。当添加veca=B+C时,所有组件都是独立的,因此该过程是可并行的

再次注意,我没有做任何与向量相关的事情。这只是一个示例,有助于大致解释我的代码的作用。不,它不把向量加在一起,但它的工作方式类似,块分配内存的元素之间没有交叉通信。我的意思是,没有处理器读写的内存超过了自己唯一分配的内存区域。如果您仍然不理解,那么就忽略数据损坏或数据竞争的可能性。它们不可能发生

回到问题上来 如果有人能帮我,我将不胜感激。当我的理解能力提高时,我可能会在以后发布一个更复杂的问题。多谢各位

注: 我删除了C++标签,用C替换它,因为这是一个C问题,不是C++。 注2: 这是一个非常狭窄的问题。我只想知道如何做三件事。这些是:

  • 在GPGPU设备上分配内存供GPGPU使用
  • 在我使用完此内存后释放/释放它
  • 访问此内存的读/写操作

首先,内核不工作的原因是您在其中使用C++标准库。CUDA C不支持这一点。因此,您不能使用std::vector或其他STL类型

你问的问题非常基本,你应该能够很容易地找到这些信息。你是想查一下还是直接来的


看这张照片。它包含了几乎完全在执行的要求。

设备代码不支持通过C++标准库分配内存(例如<代码> STD::vector < /代码>)。如果要在内核中进行动态内存分配,必须使用

malloc
free

__global__
void cuda_kernel(int N)
{
    double *vec = malloc(N * sizeof(double));
    for(int i = 0; i < N; ++ i) vec[i] = 0.0;
    free(vec);
}
\u全局__
void cuda_内核(int N)
{
double*vec=malloc(N*sizeof(double));
对于(inti=0;i

可以在一个内核中使用
malloc
,在另一个内核中使用
free
,在调用之间内存保持不变。设备代码中的
malloc
分配来自设备堆,它是设备内存的一部分。可以为
cudamaloc
(可从主机调用)提供比为
malloc
(可从设备调用)更多的内存。

您似乎忽略了更典型的选项:不要编写需要分配内存的内核。相反,调用方应该将内存传递到内核中;e、 g.传入通过
cudamaloc
获得的指针
__global__
void kernel(int N, double *vec_all)
{
    int index = threadIdx.x + blockDim.x * blockIdx.x;
    double *vec = vec_all + N * index;
    for(int i = 0; i < N; ++i) { vec[i] = 0.0; }
}