【问题标题】:How to replace CUDA function to single threaded CPU functions?如何将 CUDA 函数替换为单线程 CPU 函数?
【发布时间】: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 完成它的工作,我没有不需要调试我的那部分代码。

标签: c++ cuda


【解决方案1】:

有一些不错的 cuda 调试器可以同时调试 cpu 和 gpu,特别是您可以使用 Nvidia 的工具,例如 Cuda-gdb,它可以在 Visual Studio 或 Eclipse 中用于 cpu 和 gpu 断点。 total viewArm-ddt 等工具也需要付费。

【讨论】:

  • CUDA-GDB 适用于 linux/mac 否?
【解决方案2】:

我终于找到了解决办法,我在开头加了一句:

#ifdef STHREADED

    #define __global__
    int threadIdxX;
    int blockIdxX;
    int blockDimX;
    int gridDimX;

#else

    #include "cuda_runtime.h"
    #include "device_launch_parameters.h"

    #define threadIdxX threadIdx.x
    #define blockIdxX blockIdx.x
    #define blockDimX blockDim.x
    #define gridDimX gridDim.x

#endif

这样,在我的代码中,我可以使用 threadIdxX 而不是 threadIdx.x,而且我已经能够通过完全不使用线程来找到我正在寻找的错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 2020-02-02
    • 1970-01-01
    • 2021-06-08
    相关资源
    最近更新 更多