【发布时间】:2020-01-28 08:07:38
【问题描述】:
我正在尝试调试我的 cuda 程序,但我看起来非常不切实际,因为它是多线程的,因为您必须选择 warp,如果您想同时调试 cpu 和 gpu,还需要两个调试器时间。
我还搜索了单线程调试模式,但它似乎不存在,然后我决定在调试配置时通过添加#ifdef _DEBUG 行来修改功能。
像这样:
#ifndef DEBUG
__global__
#endif
void add(int n, float *x, float *y)
{
int index = threadIdx.x;
int stride = blockDim.x;
for (int i = index; i < n; i += stride)
y[i] = x[i] + y[i];
}
还有:
int blockSize = 256;
int numBlocks = (N + blockSize - 1) / blockSize;
ifdef _DEBUG
gridDim.x = numBlocks;
blockDim.x = blockSize;
for (threadIdx.x = 0; threadIdx.x < blockSize; threadIdx.x++)
for (blockIdx.x = 0; blockIdx.x < numBlocks; blockIdx.x++)
add(N, x, y);
#else
add<<<numBlocks, blockSize>>>(N, x, y);
cudaDeviceSynchronize();
#endif // _DEBUG
它可以工作,但编译器抱怨 gridDim.x、blockDim.x、threadIdx.x 和 blockIdx.x 不可编辑。
我试过了:
#ifdef _DEBUG
#define __global__
uint3 threadIdx;
uint3 blockIdx;
uint3 blockDim;
uint3 gridDim;
#else
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#endif
但它不再喜欢这样了,给declaration is incompatible with "const uint3 threadIdx"。
我的 c++ 知识不足以扩展找到解决方案。
编辑: 我可以像这样改变我所有的内核:
void add(int n, float *x, float *y)
{
#ifdef _DEBUG
int index=mythreadidxx;
int stride=myblockdimx;
#else
int index = threadIdx.x;
int stride = blockDim.x;
#endif
for (int i = index; i < n; i += stride)
y[i] = x[i] + y[i];
}
但这会使代码再次变得更重。
【问题讨论】:
-
这听起来像是x-y problem 的完美示例。您真正的问题是调试工具(它应该可以正常工作,并且 CUDA 工具可以调试主机代码),但是您询问您的解决方案是以某种方式尝试破解 CUDA 代码的模拟器,这对我来说似乎完全没有意义
-
@talonmies 是的,我的问题在于不实用的调试工具。是的,您可以调试线程,但线程仍然会在他们想要的时候启动,而我的需求实际上是以正确的顺序检查工作以了解我的代码中的错误。我可以使用调试器继续我想要的线程,但是当按下 F10 时线程可能会改变......这就是我想要的。
-
@talonmies 我正在尝试调试“我的代码设计”,因此能够切换到单线程 - cpu 模式来做到这一点并不荒谬,cuda 完成它的工作,我没有不需要调试我的那部分代码。