异步调用
接口调用流程
- 用户通过自定义AscendStream类构造需要的Stream实例传入异步接口,通过接口传入并在指定Stream上执行,同一Stream串行指定接口任务后可通过调用Synchronize()接口阻塞应用程序或线程运行,直到该Stream中的所有任务全部完成。
- 支持多Stream异步执行,每个Stream内接口顺序执行,如果用户使用多Stream异步执行或异步执行结果需传入不支持异步接口情况,需要用户可选择执行Synchronize()接口,在适当位置执行同步Stream操作,保证结果已正确返回供后续使用。
- 对于异步调用进行媒体数据处理时,需要调用Synchronize()接口使异步任务完成才能及时归还使用的通道,避免资源池被耗尽。
图1 Stream异步模式接口调用流程(以Resize操作为例)
mxVision提供AscendStream类进行Stream管理,关键步骤说明如下:
- 调用MxInit()接口进行全局初始化。
- 初始化Stream。
用户通过向构造函数传入“deviceId”指定要创建Stream的设备,支持的“deviceId”根据用户环境存在差异。
- 创建Stream。
与Stream初始化绑定使用,在使用Stream前需要调用CreateAscendStream()成员函数完成Stream创建。
- 调用异步接口。
- 支持异步的接口传入指定Stream,同一Stream中接口按顺序串行执行。
- 指定不同Stream的接口之间并行执行。
- 同步Stream。
- 销毁Stream。
用户在业务流程完成或Stream结束时,需调用DestroyAscendStream()成员函数销毁Stream,否则可能会造成Stream耗尽情况。
- 调用MxDeInit()接口对初始化的全局资源进行去初始化。
示例代码
以图像异步缩放和yoloV3模型异步推理为例,提供关键步骤的代码示例,不可以直接拷贝编译运行,仅供参考。
// 初始化 MxInit(); { // 用户创建目标deviceId的stream AscendStream stream(deviceId) stream.CreatAscendStream(); // 创建图像解码类实例 ImageProcessor imageProcessor(deviceId); // 解码后的Image类实例 Image decodedImage; // 根据图像路径进行解码 APP_ERROR ret = imageProcessor.Decode(imagePath, decodedImage); // 缩放后的图像类实例 Image resizedImage; // 异步调用缩放接口 ret = imageProcessor.Resize(decodedImage, Size(416, 416), resizedImage, Interpolation::HUAWEI_HIGH_ORDER_FILTER, stream); // 调用同步接口,可以显式保证调用后续接口时缩放已完成 stream.Synchronize(); // 将 Image 类转换为 Tensor 类 Tensor tensorImg = resizedImage.ConvertToTensor(); // yoloV3模型推理 string yoloPath = "./model/yolov3_tf_bs1_fp16.om"; Model yoloV3(yoloPath, deviceId); // 构造推理输入输出 (单batch) vector<Tensor> yoloV3Inputs = {tensorImg}; vector<Tensor> yoloV3Outputs = {}; // 开始异步推理 ret = yoloV3.Infer(yoloV3Inputs, yoloV3Outputs,stream); // 调用同步接口,可以显式保证调用后续接口时缩放已完成 // 用户也可选择同步前在该stream串行其他异步接口 stream.Synchronize(); // 调用DestroyAscendStream销毁stream stream.DestroyAscendStream(); } //去初始化 MxDeInit();
父主题: 使用API接口方式开发(C++)