性能优化之taskflow

参考链接

https://taskflow.github.io/taskflow/install.html

https://github.com/szandara/cpp-taskflow?tab=readme-ov-file  info

https://dreampuf.github.io/GraphvizOnline/

https://taskflow.github.io/tfprof/

https://www.oschina.net/p/cpp-taskflow
https://github.com/taskflow/taskflow/releases/tag/v3.5.0
https://github.com/taskflow/taskflow
https://taskflow.github.io/taskflow/index.html
https://www.zywvvd.com/notes/coding/cpp/taskflow/taskflow/

官方资料

编译官例

我使用的版本是3.5,

~$ mkdir build
~$ cd build
~$ cmake ../
~$ make                         # compile all examples and unittests
~$ make test

运行官例出现如下报错:

taskflow/algorithm/for_each.hpp:131:5: 错误:‘B_t’在此作用域中尚未声明
taskflow/algorithm/for_each.hpp:132:5: 错误:‘E_t’在此作用域中尚未声明
taskflow/algorithm/for_each.hpp:133:5: 错误:‘S_t’在此作用域中尚未声明
taskflow/algorithm/for_each.hpp:135:25: 错误:‘beg’未被捕获
taskflow/algorithm/for_each.hpp:135:30: 错误:‘end’未被捕获
taskflow/algorithm/for_each.hpp:135:8: 错误:‘is_range_invalid’的实参不依赖模板参数,所以‘is_range_invalid’的声明必须可用

加上-std=c++17后就解决了。后面的官例大家可以看 Taskflow:异步任务(Asynchronous Tasking)-CSDN博客 https://blog.csdn.net/jj147258369/category_12624347.html 这个博主,他理解得透彻一些。而我现在只是为了追求性能蛮试。

parallel_data_pipeline

运行官例parallel_data_pipeline,结果:

 将输出的拓扑图代码复制到在线查看网站:Graphviz Online

 Tsung-Wei Huang的cpp-taskflow

由pdf第3章可以知道,有5种任务调度模式:static task, dynamic task, composable task, condition

task , and cudaFlow task 。
静态调度是指任务层次平坦,无法从正在运行的任务图中创建新的任务。我觉得静态调度就是只有唯一一条任务线(主线),很顺的从头走到尾。如下图的:A--(B,C)--D
动态调度涉及父任务、子任务,如下图的静态线A--(B,C)--D就是父任务,而(B2,B1)--B3--B就是子任务。

组合任务使开发者可以自行决定任务层次,可以通过组合模块化、重复的单元形成更大的任务。这可以提高产能和并行编程的可伸缩性。如下图C--D--E是静态线(主taskflow),而D1--D2--D是动态线,E是一个模块化任务单元(单独的一个taskflow)。

而下图是一个不正确的组合任务示例:因为这两个相同的模块化任务F1会导致竞争???

我的实例

静态task

我的实例是参考简单的官例写的,都是静态task,部分代码与输出如下:

A.name("A");
B.name("B");
C.name("C");
D.name("D");
E.name("E");
F.name("F");
G.name("G");
H.name("H");
I.name("I");
J.name("J");


B.precede(C, D);
D.precede(E, F,G);
H.succeed(E, G);
I.succeed(F);
J.succeed(A, C,I,H);


digraph Taskflow {
subgraph cluster_p0x7ffc8c8b3080 {
label="Taskflow: simple";
p0x2bb7f60[label="J" ];
p0x2bb8050[label="I" ];
p0x2bb8050 -> p0x2bb7f60;
p0x2bb8140[label="H" ];
p0x2bb8140 -> p0x2bb7f60;
p0x2bb8230[label="G" ];
p0x2bb8230 -> p0x2bb8140;
p0x2bb8320[label="F" ];
p0x2bb8320 -> p0x2bb8050;
p0x2bb8410[label="E" ];
p0x2bb8410 -> p0x2bb8140;
p0x2bb8500[label="D" ];
p0x2bb8500 -> p0x2bb8410;
p0x2bb8500 -> p0x2bb8320;
p0x2bb8500 -> p0x2bb8230;
p0x2bb85f0[label="C" ];
p0x2bb85f0 -> p0x2bb7f60;
p0x2bb86e0[label="B" ];
p0x2bb86e0 -> p0x2bb85f0;
p0x2bb86e0 -> p0x2bb8500;
p0x2bb87d0[label="A" ];
p0x2bb87d0 -> p0x2bb7f60;
}
}

拓扑图如下,这和我设计的流程是一致的:

 可是性能对比好像并没有太大的提升???

是不是不该用静态,因为这并不是一条很顺的主线。应该用动态?组合? 

我profile一下,按照官网:

touch /root/TFresult.json
export TF_ENABLE_PROFILER=/root/TFresult.json
./xxxx_your_run_file_xxx

将这个json文件拷贝到Taskflow Profiler 下面的框中:

可以看到我的都是浅蓝色的,因为表示static即静态。末端的柱状图表示对每个task根据耗时排序的结果。鼠标点击任意位置即可出现task名称以及相关信息:

左边显示的E0即Executor0,因为我的确只创建了1个executor。W即表示Worker,这4个worker自动生成的?L0表示Level0,也是自动生成?

可以看到主要是W1最耗时,怎么继续优化我想想

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

元气少女缘结神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值