使用Tengine Explore版在firefly-RK3399上开发多线程项目

这是Tengine Explore版本系列文章的第二篇。

上一篇,我们讲到,使用Tengine Explore版本在firefly-RK3399上实现了实时目标检测的一个demo,并且对比了开源版,Explore版(float32),Explore版(int8)三者的性能。本篇,我们将在此基础上进一步挖掘Tengine Explore和firefly-RK3399的强大性能。

Tengine不仅支持在ARM架构的芯片上使用CPU进行推理,还支持使用CPU/GPU异构计算,充分发挥硬件的性能,详情请看官方文档:Tengine/doc/gpu_cpu_mssd.md,其中GPU采用float16进行推理运算。

由于我们的应用需要两路视频同时处理,因此我们需要用到多线程。多线程的应用开发也可以参考官方的文档:Tengine/doc/multi_thread_mssd.md和例子:Tengine/tests/bin/mt_mssd.cpp

RK3399的CPU采用big.LITTLE大小核架构,双Cortex-A72大核+四Cortex-A53小核结构,GPU采用的是Mali-T864,硬件条件还是很不错的。上一篇文章中,程序默认使用A72来进行计算,并且测试得到的时间包含了图像预处理、模型推理和后处理三部分。

本文重点放在多线程的使用,以及如何调用不同的核心。并且为了更加准确地衡量推理本身的速度,本文中的时间仅包含模型推理的时间,不含图像预处理和后处理的时间。

Tengine是专门针对嵌入式设备的前向推理框架,对3399的支持可以说很友好了。使用Tengine开发多线程应用,可以轻松地实现计算资源的调度。例如我们启动两个线程,并且一个线程用A72,另一个用A53来跑模型,可以简单地通过以下代码来实现:

const struct cpu_info * p_info = get_predefined_cpu("rk3399");
int a72_list[] = { 4, 5 };           //two a72 cores
set_online_cpu((struct cpu_info *)p_info, a72_list, sizeof(a72_list)/sizeof(int));
create_cpu_device("a72", p_info);

const struct cpu_info* p_info1 = get_predefined_cpu("rk3399");
int a53_list[] = { 0, 1, 2, 3 };    //four a53 cores
set_online_cpu((struct cpu_info*)p_info1, a53_list, sizeof(a53_list)/sizeof(int));
create_cpu_device("a53", p_info1);

std::thread *thread1 = new std::thread(your thread_function1);
std::thread *thread2 = new std::thread(your thread_function2);

thread1->join();
thread2->join();

delete thread1;
delete thread2;

//in thread_function1:
graph_t graph = create_graph(nullptr, "caffe", text_file, model_file);  //Tenigne API 2.0
set_graph_device(graph, "a72");

//in thread_function2:
graph_t graph = create_graph(nullptr, "caffe", text_file, model_file);  //Tenigne API 2.0
set_graph_device(graph, "a53");

接下来,我们分别将线程1和线程2绑定到不同的处理核心上,来测试性能。测试方法还是跟上一篇一样,使用两个线程同时处理两路本地视频,计算每一帧的平均时间,并分别采用float32和int8进行推理,模型还是跟上一篇文章用的一样,是在Mobilenet_SSD的基础上裁剪压缩得到的,大小为8.3M。结果如下表(线程时间表示该线程处理一帧的平均时间,以及换算成fps之后的值,不包含图像预处理以及后处理的时间):

运算方式 线程1核心 线程2核心 线程1时间 线程2时间
float32 A72 A53 27.7ms/36.1fps 37.0ms/27.0fps
float32 A72 GPU(float16) 29.2ms/34.2fps 99.4ms/10.1fps
float32 A53 GPU(float16) 38.5ms/26.0fps 103.6ms/9.7fps
int8 A72 A53 24.6ms/40.7fps 33.3ms/30.0fps
int8 A72 GPU(float16) 26.3ms/38.0fps 97.3ms/10.3fps
int8 A53 GPU(float16) 34.3ms/29.2fps 101.7ms/9.8fps

可以看到,A72的运算是最快的,其次A53,最后是GPU。GPU上的运算时间有待提升。量化方式比浮点方式速度更快!但是由于我们的模型已经压缩得很小了,所以量化计算的加速比没有那么明显。但是采用量化计算,两个线程分别用2个A72和4个A53,fps分别达到40.7和30.0,相当快了!

参与Tengine AloT 树莓派/RK3399应用征集大赛,每个开发者可以体验性能非凡的Tengine Explore版。微信扫描以下二维码参与活动:
使用Tengine Explore版在firefly-RK3399上开发多线程项目_第1张图片

你可能感兴趣的:(使用Tengine Explore版在firefly-RK3399上开发多线程项目)