- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我最近发现了 cuda-memcheck 的 racecheck 工具,可用于 CUDA 5.0(cuda-memcheck --tool racecheck
,请参阅 NVIDIA doc)。该工具可以检测 CUDA 内核中共享内存的竞争条件。
在 Debug模式下,这个工具没有检测到任何东西,这显然是正常的。但是,在 Release模式 (-O3) 中,我会根据问题的参数得到错误。
下面是一个错误示例(第22行初始化共享内存,第119行赋值):
========= ERROR: Potential WAW hazard detected at shared 0x0 in block (35, 0, 0) : ========= Write Thread (32, 0, 0) at 0x00000890 in ....h:119:void kernel_test3(Data*) ========= Write Thread (0, 0, 0) at 0x00000048 in ....h:22:void kernel_test3(Data*)
========= Current Value : 13, Incoming Value : 0
threadIdx.x
上添加了额外的检查,但这并没有改变什么。__shared__ float arr[SIZE_1][SIZE_2][NB_THREADS_PER_BLOCK]
.我真的不明白怎么会有竞争条件,因为每个线程都处理自己的共享内存部分。为了了解发生了什么,我测试了一些更简单的内核。让我向您展示一个导致此类错误的内核示例。基本上,这个内核使用 SIZE_X*SIZE_Y*NTHREADS*sizeof(float)
B 的共享内存,每个 SM 我可以使用 48KB 的共享内存。
test.cu
template <unsigned int NTHREADS>
__global__ void kernel_test()
{
const int SIZE_X = 4;
const int SIZE_Y = 4;
__shared__ float tmp[SIZE_X][SIZE_Y][NTHREADS];
for (unsigned int i = 0; i < SIZE_X; i++)
for (unsigned int j = 0; j < SIZE_Y; j++)
tmp[i][j][threadIdx.x] = threadIdx.x;
}
int main()
{
const unsigned int NTHREADS = 32;
//kernel_test<NTHREADS><<<32, NTHREADS>>>(); // ---> works fine
kernel_test<NTHREADS><<<64, NTHREADS>>>();
cudaDeviceSynchronize(); // ---> gives racecheck errors if NBLOCKS > 32
}
编译:
nvcc test.cu --ptxas-options=-v -o test
如果我们运行内核:
cuda-memcheck --tool racecheck test
kernel_test<32><<<32, 32>>>();
: 32 个 block ,32 个线程 => 不会导致任何明显的 racecheck 错误。kernel_test<32><<<64, 32>>>();
: 64 个 block ,32 个线程 => 导致 WAW 危险(threadId.x = 32?!)和错误。========= ERROR: Potential WAW hazard detected at shared 0x6 in block (57, 0, 0) :
========= Write Thread (0, 0, 0) at 0x00000048 in ....h:403:void kernel_test(void)
========= Write Thread (1, 0, 0) at 0x00000048 in ....h:403:void kernel_test(void)
========= Current Value : 0, Incoming Value : 128========= INFO:(Identical data being written) Potential WAW hazard detected at shared 0x0 in block (47, 0, 0) :
========= Write Thread (32, 0, 0) at 0x00000048 in ....h:403:void kernel_test(void)
========= Write Thread (0, 0, 0) at 0x00000048 in ....h:403:void kernel_test(void)
========= Current Value : 0, Incoming Value : 0
那么我在这里缺少什么?我在共享内存上做错了吗? (我还是初学者)
问题似乎来自cudaDeviceSynchronize()
什么时候NBLOCKS > 32
.为什么会这样?
最佳答案
对于初学者来说,cudaDeviceSynchronize() 不是原因;你的内核是原因,但它是一个异步调用,所以错误是在你调用 cudaDeviceSynchronize() 时捕获的。
至于内核,您的共享内存大小为 SIZE_X*SIZE_Y*NTHREADS(在示例中转换为每个 block 512 个元素)。在您的嵌套循环中,您使用 [i*blockDim.x*SIZE_Y + j*blockDim.x + threadIdx.x] 对其进行索引——这就是您的问题所在。
更具体地说,您的 i 和 j 值范围为 [0, 4),您的 threadIdx.x 范围为 [0, 32),您的 SIZE_{X | Y} 的值为 4。当 blockDim.x 为 64 时,循环中使用的最大索引将为 991(从 3*64*4 + 3*64 + 31)。当您的 blockDim.x 为 32 时,您的最大索引将为 511。
根据你的代码,只要你的 NBLOCKS 超过你的 NTHREADS,你就会得到错误
关于CUDA racecheck、共享内存阵列和 cudaDeviceSynchronize(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13861017/
我遇到了一个非常奇怪的错误,在运行特定大小的 Heat 2D 模拟时出现“非法内存访问”错误,但如果我运行完全相同的模拟,模拟运行良好,只是元素更少。 是否有增加数组大小会导致此异常的原因?我使用的是
我是 CUDA 的新手,对 cudaEvent 有点困惑。我现在有一个代码示例,如下所示: float elapsedTime; cudaEvent_t start, stop; CUDA_ERR_C
我有以下两个几乎相同的示例代码。 code1.cu 使用 cudaMalloc 和 cudaMemcpy 处理设备/主机变量值交换。 code2.cu使用cudaMallocManaged,因此不需要
什么时候真正需要调用cudaDeviceSynchronize函数? 据我从 CUDA 文档中了解到,CUDA 内核是异步的,因此我们似乎应该在每次内核启动后调用 cudaDeviceSynchron
我正在具有统一内存的 TegraK1 板上实现共轭梯度求解器。我面临的问题是在循环中我必须执行 cudaDeviceSynchronize();两次更新变量,与 TI Keystone-II 相比,这
我最近发现了 cuda-memcheck 的 racecheck 工具,可用于 CUDA 5.0(cuda-memcheck --tool racecheck,请参阅 NVIDIA doc)。该工具可
我在使用并发 CUDA 时遇到了一些问题。看看附图。内核在标记点启动,即 0.395 秒。然后是一些绿色的 CpuWork。最后,调用 cudaDeviceSynchronize。在 CpuWork
我在使用并发 CUDA 时遇到了一些问题。看看附图。内核在标记点启动,即 0.395 秒。然后是一些绿色的 CpuWork。最后,调用 cudaDeviceSynchronize。在 CpuWork
CUDA 版本 10.1。帕斯卡GPU。所有命令都发布到默认流: void * ptr; cudaMalloc(&ptr, ...); launch_kernel>>(ptr); cudaDevice
我用 CUDA 6.5 和 4 x GPU Kepler . 我使用多线程、CUDA 运行时 API 并从不同的 CPU 线程访问 CUDA 上下文(通过使用 OpenMP - 但它并不重要)。 当我
这三个函数有什么区别,尤其是最后两个?图书馆手册说 Note that this function is deprecated because its name does not reflect it
非常感谢您阅读我的帖子。 我正在做 CUDA 工作,但一直收到 cudaDeviceSynchronize() 错误代码 77:cudaErrorIllegalAddress,不知道为什么。我搜索了代
__global__ void helloCUDA(float f) { printf("Hello thread %d, f=%f\n", threadIdx.x, f); } int ma
我是一名优秀的程序员,十分优秀!