算法耗时通用优化技巧 总结

发布时间:2024-12-19 14:37

定期回顾工作,总结经验和优化方法 #生活技巧# #工作效率#

最近在部署AI相关的算法,并要求减少总耗时,从中总结出的一些比较通用的优化技巧。精髓总结一句话就是:在同一时间尽可能充分利用硬件资源。而怎么尽可能充分利用呢,方式就是多线程并行处理

1、单线程串行处理数据

假设算法需要处理两份同类型的数据(适用场景可以扩展到:算法需要处理两份及以上同类型的数据,或者对算法内部进行优化),最简单的就是采用单线程先后处理,如下图1:

 图1 串行处理多份同类型数据

2、多线程并行处理同类型数据

串行方式的缺点是对硬件的使用率非常低,比如处理每份数据都要经过数据加载、计算、保存等操作,那么同一时间数据在加载传输到内存的时候cpu是空闲的,最好的情况是在加载传输第二份数据的时候cpu正在对第一份数据计算。提高各个硬件资源的利用率的方法就是“多线程并行”,如下图2所示创建两个线程,每个线程分别处理一份同类型数据:

 图2 多线程并行处理同类型数据

c++实现代码如下:

#include <thread>

using namespace std;

auto func_proc=[](Ai* mai,float* data){

mai->Proc(data);

};

Ai mai1,mai2;

float* data1,data2;

thread t1(func_proc,&mai1,data1);

thread t2(func_proc,&mai2,data2);

t1.join();

t2.join();

3、拆分成各子模块之间的并行

但是上面这种并行方式资源占用是比较多的,相当于同时申请了两份Ai资源,如果Ai资源内存或者显存占用很多势必会影响其他算法性能。因此有一种解决方案就是对Ai进行拆分(如下图3所示),比如这里拆分成4个子模块,子模块之间尽可能解耦(可以有相互依赖关系)。这样当线程2处理子模块A时会先等待线程1执行完子模块A,当线程1执行完子模块B时,线程2执行子模块A,达到子模块之间并行。从理论上来说,对算法模块拆分越精细,则对硬件利用率越高。

  图 3.各个子模块之间并行

代码上实现这种并行方式,可以对每个子模块加一个互斥锁,如下图4所示。

  图 4.通过加互斥锁达到各子模块间的并行

c++代码如下:

#include <thread>

#include <mutex>

using namespace std;

auto func_proc=[&](Ai* mai,float* data,mutex* mylocks){

{

std::lock_guard<std::mutex> tmpLock(mylocks[0]);

auto outA=mai->subA(data);

}

{

std::lock_guard<std::mutex> tmpLock(mylocks[1]);

auto outB=mai->subB(outA);

}

{

std::lock_guard<std::mutex> tmpLock(mylocks[2]);

auto outC=mai->subC(outB);

}

{

std::lock_guard<std::mutex> tmpLock(mylocks[3]);

auto outD=mai->subD(outC);

}

};

Ai mai1;

float* data1,data2;

mutex mylocks[4];

thread t1(func_proc,&mai1,data1,mylocks);

thread t2(func_proc,&mai1,data2,mylocks);

t1.join();

t2.join();

4、独立子模块之间的并行 

进一步,如果子模块之间有相互独立的,则可以并行起来,如下图所示:

  图 5.独立子模块之间的并行

网址:算法耗时通用优化技巧 总结 https://www.yuejiaxmz.com/news/view/518884

相关内容

智能家居能耗优化算法
最优化算法——常见优化算法分类及总结
OpenCV常见的优化方法和技巧总结
算法优化大揭秘:12个加速算法运行速度的实用技巧
动态规划算法的优化技巧(转贴)
实验一 算法优化技巧与时间复杂度
算法优化的艺术:降低时间复杂度与提升算法效率的实战技巧
算法小技巧:空间换时间,时间换空间?
家用电器与日常生活优化总结(10页)
优化时间利用的时间管理技巧.docx

随便看看