c++ - CUDA 内核 printf() 在终端中不产生输出,在分析器中工作

标签 c++ cuda

<分区>

考虑以下程序:

#include <cuda/api_wrappers.hpp>

namespace kernels {
template <typename T>
__global__ void print_stuff()
{
        printf("This is a plain printf() call.\n");
}
} // namespace kernels

int main()
{
        auto launch_config { cuda::make_launch_config(2,2) };
        cuda::launch(::kernels::print_stuff<int>, launch_config);
        cuda::outstanding_error::ensure_none();
}

(它使用 cuda-api-wrappers 库)。

程序编译运行。但是,如果我在终端中运行,它什么也不打印; 而如果我通过 nvvp 运行它,控制台会显示:

This is a plain printf() call.
This is a plain printf() call.
This is a plain printf() call.
This is a plain printf() call.

...如预期(2 个 block x 2 个线程 = 4 行)。

我没有在终端上打印四行的原因是什么/可能是什么?

注意事项:

  • 我意识到理论上问题可能出在图书馆,我是图书馆的作者。所以“它必须是图书馆”是一个合理的答案,但你需要解释为什么它不能是其他任何东西。
  • 使用 nvcc -Xcompiler -Wall -Xcompiler -Wextra 编译时没有警告。
  • 我使用 Devuan GNU/Linux 3(beowulf;相当于 Debian Buster)。
  • 我的硬件:AMD64 Intel CPU;一张 GTX 1050 Ti 卡。
  • nVIDIA 驱动程序版本:430.50; CUDA 版本:10.1.105。
  • cuda-memcheck 不提示程序。

最佳答案

main() 完成时,您隐含地错误地假设了特定的发生顺序。具体来说,您假设因为默认流是同步的,所以在内核启动后执行下一行代码时,与您的内核有关的所有事情都已经结束并完成。这不是 100% 正确——正如@RobertCrovella 所暗示的那样;具体来说,不能保证设备的 printf() 缓冲区会在控制返回到您的程序之前传送回主机内存并转储到标准输出流中。

您需要将(默认的,当前的)CUDA 设备与主机同步,即执行:

cuda::device::current::get().synchronize();

或者至少同步设备的默认流:

cuda::device::current::get().default_stream().synchronize();

确保printf() 结果成为标准输出。

现在,nvvp 以某种方式检测您的执行(可能只是通过运行探查器 - 但 nvprof 通过 Hook (CUDA 运行时 API 调用)检测执行)。因此,当您以这种方式运行程序时,行为会有所不同。


有点相关的问题:The behavior of stream 0 (default) and other streams .

关于c++ - CUDA 内核 printf() 在终端中不产生输出,在分析器中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58531349/

相关文章:

c# - C++ char* 和 C# 字节

c++ - 访问每个矩阵点

c++ - CUDA 中 3D 三角网格的最佳内存数据结构是什么?

c++ - 如何理解将半精度指针转换为无符号long long指针以及相关的内存对齐方式?

c++ - 如何在 C++ 中创建列表?

c++ - 指向数组子集的智能指针 (c++11)

c++ - 如何在 C++ 中将 CHAR 变量复制到 WCHAR 变量

c++ - CUDA,使用2D和3D阵列

python - CUDA-Python : How to launch CUDA kernel in Python (Numba 0. 25)?

c++ - 在 Visual Studio 2015 中检查 STL 容器