[英]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
编译时没有警告。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.