异步调用
功能介绍
mxVision默认采用同步执行模式,部分接口已支持用户通过申请AscendStream异步执行,具体接口异步支持情况请参见《MindX SDK mxVision 用户指南》的“API参考(C++)”章节。
接口调用流程
- 用户通过自定义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++)