cuda流:流执行后未调用回调
cuda streams: callback not getting called after stream execution
我在使用cuda流回调函数时遇到问题。问题是它在内核运行后不会执行。我将cuda流封装在一个C++类中,如下所示:
class Stream
{
public:
Stream();
void run(float *input, int points);
~Stream();
static void CUDART_CB callback(cudaStream_t stream,
cudaError_t status,
void * user_data);
private:
void callback_function();
cudaStream_t s;
};
现在,我有了回调函数设置,如前所述,如下所示:
void CUDART_CB StreamWorkflow::callback(cudaStream_t stream,
cudaError_t status,
void * user_data)
{
Stream* thiz = (Stream *)(user_data);
thiz->callback_function();
}
构造函数设置流并附加回调
Stream::Stream()
{
checkCudaErrors(cudaStreamCreate(&s));
checkCudaErrors(cudaStreamAddCallback(s, Stream::callback, this, 0));
}
现在run方法在这个流上调用cuda内核,我知道它执行得很好。它的实现方式如下:
void Stream::run(float *f, int p)
{
dim3 block(16, 16);
dim3 grid((int)ceil(double(p) / 256.0));
my_kernel(f, p, grid, block, s);
checkCudaErrors(cudaDeviceSynchronize());
getLastCudaError("kernel launch failed");
}
我的问题是回调只有在构造函数被执行时才会被调用。因此,一旦创建了对象,callback_function()就会通过注册的callback()执行。内核被主机多次执行,并且在完成时从不执行回调函数。我可以看到内核执行成功,但回调从未到来。
每次运行内核时,我都必须注册回调(所以在执行run函数之前注册此回调),还是我在这里真的做错了什么?
我想您可能对回调的工作方式感到困惑。通常,当向CUDA流发出CUDA操作时,该CUDA操作将在向该流发出的所有先前CUDA活动都已完成时(以及在开始向该流发送的任何后续活动之前)执行。
回调也不例外。如果您希望在内核执行后执行回调,那么您必须在发出内核后向该流发出回调。添加回调函数的定义是而不是:
"任何时候内核在这个流中完成,运行这个回调">
添加回调函数的定义是:
"当CUDA流至此完成所有CUDA活动时,执行回调">
或者,直接从文档中引用:
在前面的流操作完成后调用的函数
因此,这个构造函数对我来说毫无意义:
Stream::Stream()
{
checkCudaErrors(cudaStreamCreate(&s));
checkCudaErrors(cudaStreamAddCallback(s, Stream::callback, this, 0));
}
这个构造函数说:
"创建CUDA流">
"当以前向该流发出的所有活动都完成时,运行此回调">
但当然,您还没有向该流发出任何活动,因此回调会在流创建后立即运行(并且只运行一次)。
"所以在执行运行函数之前注册此回调">
不,如果这是你想要的:
问题是在内核运行后它不会执行
然后在内核启动之后将添加回调函数移动到,我认为您更有可能看到所需的活动。
- 用于在回调中调用解析器的设计模式
- 从不同的 cpp 调用回调函数会导致bad_function_call
- 处理类内的回调时,必须调用对非静态成员函数的引用
- MSVC __debugbreak() 与 openGL 错误回调一起使用时不会产生调用堆栈
- LIBEV 非阻滞套接字连续调用回调
- 共享指针和回调注册的结构.由于我之外的原因调用回调时,原始指针值发生了变化
- 统一处理具有协变类型的函数指针(如何使用派生类型调用回调?
- 在本机节点中的回调中调用回调
- boost asio,async_read和acync_write未调用回调
- cuda流:流执行后未调用回调
- VDS(虚拟磁盘服务)COM接口通知-仅在注销期间调用回调(接收器)(Unadvise)
- 提升 ASIO,async_read_some未调用回调
- 如何在成员函数线程中调用回调
- 从c++向目标c调用回调函数
- c++调用回调后删除对象
- 可调用(回调)作为类模板参数的模板
- 在异步API (c++)中,如何保证API在调用回调之前返回
- 装饰器模式:如何从核心类中调用(回调)装饰器包装器的一些成员
- Cython使用python-c-api调用回调segfault
- 为什么boost asio async_read_some在特定情况下不调用回调