繁体   English   中英

CUDA kernel printf() 在终端中不产生 output,在分析器中工作

[英]CUDA kernel printf() produces no output in terminal, works in profiler

考虑以下程序:

#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 个块 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()完成时,您隐含地错误地假设出现的特定顺序。 具体来说,您假设因为默认的 stream 是同步的,所以与您的 kernel 相关的一切都已经结束,并且在 Z50484C19F1AFDAF38421A0D821ED39 启动后的下一行代码执行时完成。 这不是 100% 正确的——正如@RobertCrovella 所暗示的那样; 具体来说,不能保证设备的printf()缓冲区会在控制权返回您的程序之前被传送回主机 memory 并转储到标准 output stream 中。

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

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

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

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

确保printf()结果符合标准 output。

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


有点相关的问题: stream 0 (default) 和其他流的行为

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM