Stream管理
本节介绍单Stream、多Stream的创建、销毁流程,以及多Stream同步等待的流程。
在AscendCL中,Stream是一个任务队列,应用程序通过Stream来管理任务的并行,一个Stream内部的任务保序执行,即Stream根据发送过来的任务依次执行;不同Stream中的任务并行执行。一个默认Context下会挂一个默认Stream,如果不显式创建Stream,可使用默认Stream,默认Stream作为接口入参时,直接传NULL。
AscendCL提供以下几种Stream管理机制:
其中,多Stream场景下的同步等待流程请参见Stream间任务的同步等待接口调用流程及示例代码。
单线程单Stream
调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝编译运行,仅供参考。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include "acl/acl.h"
// ......
int32_t deviceId = 0;
// 指定运算的Device
aclrtSetDevice(deviceId);
// 显式创建一个Stream
aclrtStream stream;
aclrtCreateStream(&stream);
// 调用触发任务的接口,传入stream参数
aclrtMemcpyAsync(dstPtr, dstSize, srcPtr, srcSize, ACL_MEMCPY_HOST_TO_DEVICE, stream);
// 调用aclrtSynchronizeStream接口,阻塞应用程序运行,直到指定Stream中的所有任务都完成。
aclrtSynchronizeStream(stream);
// Stream使用结束后,显式销毁Stream
aclrtDestroyStream(stream);
// ......
|
单线程多Stream
调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝编译运行,仅供参考。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include "acl/acl.h"
// ......
int32_t deviceId = 0;
uint32_t modelId1 = 0;
uint32_t modelId2 = 1;
aclrtStream stream1;
aclrtStream stream2;
// 指定运算的Device
aclrtSetDevice(deviceId);
// 创建stream1
aclrtCreateStream(&stream1);
// 调用触发任务的接口,例如异步模型推理,任务下发在stream1
aclmdlDataset *input1;
aclmdlDataset *output1;
aclmdlExecuteAsync(modelId1, input1, output1, stream1);
// 创建stream2
aclrtCreateStream(&stream2);
// 调用触发任务的接口,例如异步模型推理, 任务下发在stream2
aclmdlDataset *input2;
aclmdlDataset *output2;
aclmdlExecuteAsync(modelId2, input1, output2, stream2);
// 流同步
aclrtSynchronizeStream(stream1);
aclrtSynchronizeStream(stream2);
// 释放资源
aclrtDestroyStream(stream1);
aclrtDestroyStream(stream2);
// ....
|
多线程多Stream
调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝编译运行,仅供参考。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include "acl/acl.h"
// ......
void runThread() {
int32_t deviceId =0;
// 指定运算的Device
aclrtSetDevice(deviceId);
// 显式创建一个Stream
aclrtStream stream;
aclrtCreateStream(&stream);
// 调用触发任务的接口
// ....
// 释放资源
aclrtDestroyStream(stream);
}
// 创建2个线程,每个线程内部创建一个Stream
std::thread t1(runThread);
std::thread t2(runThread);
// 显式调用join函数确保结束线程
t1.join();
t2.join();
|
父主题: 运行时管理