c++ - 为什么 CUDA 中的外部共享内存存在未定义的行为?

标签 c++ c memory memory-management cuda

我正在尝试了解 CUDA 中共享内存的动态分配。我编写了一个简单的程序,它使用 cudaGetLastError 返回错误。我在启动内核时分配了大小为 100 个整数元素的共享内存。我尝试访问 101-127 个索引内存元素,它没有显示任何错误,但在访问第 130 个元素时,它给出错误“未指定的启动失败”。我认为在访问 101 个元素时应该会出现此错误,因为我只为 100 个元素分配了大小。

#include <cuda.h>
#include <stdio.h>
__global__ void xyz(int offset)
{
 extern __shared__ int array[];
 array[101]=offset; 
 printf("%d\n", array[101]);
}

int main()
{
 dim3 grid(1,1,1);
 dim3 block(100,1,1);
 int offset=50;
 xyz<<<grid,block,sizeof(int)*100>>>(offset);
 cudaDeviceSynchronize();
 cudaError_t err=cudaGetLastError();
 if(err!=cudaSuccess)
 {
    printf("Error is =%s\n",cudaGetErrorString(err));
 }
 return 0;
}

最佳答案

一般来说,我认为访问主机上数组末尾之外的内容(在普通 C/C++ 代码中)不会立即触发错误(例如 seg 错误等)

在 GPU 上,没有硬件机制可以跟踪字节级别的所有分配。有一种通用的硬件机制可以跟踪分配的内存页面,并发现访问是否在有效页面之外,但粒度并没有下降到字节或元素级别(我不认为这是这样的)主机 CPU 之一)。

从架构上来说,较新的 GPU 具有更好的硬件访问跟踪机制。此外,cuda-memcheck 可以对访问进行更严格的跟踪,但代价是显着降低性能,因为它执行部分基于软件的跟踪和部分基于硬件的跟踪,可能有点类似于主机上的 valgrind 等工具。

因此,尽管您似乎期望任何与分配空间的偏差都会立即触发故障,但 GPU 硬件本身并不支持这一点(并且 AFAIK CPU 硬件也不支持,至少在现代按需分页虚拟内存操作系统中) )。通过软件干预(即 cuda-memcheck),情况总体上有所改善,但仍会因硬件生成而异。

关于c++ - 为什么 CUDA 中的外部共享内存存在未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26750151/

相关文章:

c++ - 将自定义类型与 Boost 程序选项一起使用

objective-c - 成员引用基类型 'void' 不是结构或 union (OBJ-C)

java - 类设计最小化内存使用 : if an object instance variable (non-primitive) is null does it still use the necessary reference bytes?

sql - 低内存销毁操作

c++ - 从反向离散 FFT 到频谱图

c++ - 在 CPU 上并行减少数组

c++ - C++ 标准对局部变量的存储、分配有什么保证?

c - 在C中从HTML <a></a>标签中解析URL的信息

c - 将 xml 值映射到结构体值

c - 编译器是否为最大的代码块或 C 中的所有 block 保留内存?