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 22 23 24 25 26 27 | #include "acl/acl.h" // ...... void runThread(aclrtStream stream) { int32_t deviceId =0; // 指定运算的Device aclrtSetDevice(deviceId); // 显式创建一个Stream aclrtStream stream; aclrtCreateStream(&stream); // 调用触发任务的接口 // .... // 释放资源 aclrtDestroyStream(stream); } aclrtStream stream1; aclrtStream stream2; // 创建2个线程,每个线程对应一个Stream std::thread t1(runThread, stream1); std::thread t2(runThread, stream2); // 显式调用join函数确保结束线程 t1.join(); t2.join(); |
父主题: 运行时管理