有的读者们可能会对前文提到的“对所有可能的结果或行为进行排列组合和置换”产生疑问。众所周知,对可能行为的简单排列组合就会导致阶乘式的“爆炸”。当然目前有许多用于避免这类指数级爆炸的算法,Loom 中采用的核心算法是基于“动态子集缩减”算法(dynamic partial reduction)。该算法能够动态“修剪”会导致一致执行结果的排列子集,但需要注意的是,即便如此,在状态空间巨大时也一样会导致修剪效率大幅降低。Loom 采用了有界动态子集缩减算法来限制搜索空间。
总而言之,Loom 极大地帮助了我们,使得我们更有信心地发布新版调度器。
测试结果
我们来具体看看新版 Tokio 调度器到底取得了多大的性能提升?
首先,在微基准测试中,新版调度器提升显著。
老版本
- test chained_spawn ... bench: 2,019,796 ns/iter (+/- 302,168) test ping_pong ... bench: 1,279,948 ns/iter (+/- 154,365) test spawn_many ... bench: 10,283,608 ns/iter (+/- 1,284,275) test yield_many ... bench: 21,450,748 ns/iter (+/- 1,201,337)
新版本
- test chained_spawn ... bench: 168,854 ns/iter (+/- 8,339) test ping_pong ... bench: 562,659 ns/iter (+/- 34,410) test spawn_many ... bench: 7,320,737 ns/iter (+/- 264,620) test yield_many ... bench: 14,638,563 ns/iter (+/- 1,573,678)
测试内容包括:
- chained_spawn测试会递归地不断产生新的子任务。
- ping_pong测试会分配一个一次性地(oneshot)通道,接着产生一个新的子任务,子任务在该通道上发送消息,原任务则接受消息。
- spawn_many测试会产生出大量子任务,并注入给调度器。
- yield_many 会测试一个唤醒自己的任务。
为了更接近真实世界的工作负载,我们再试试 Hyper 基准测试:
- wrk -t1 -c50 -d10
老版本
- Running 10s test @ http://127.0.0.1:3000 1 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 371.53us 99.05us 1.97ms 60.53% Req/Sec 114.61k 8.45k 133.85k 67.00% 1139307 requests in 10.00s, 95.61MB read Requests/sec: 113923.19 Transfer/sec: 9.56MB
新版本
- Running 10s test @ http://127.0.0.1:3000 1 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 275.05us 69.81us 1.09ms 73.57% Req/Sec 153.17k 10.68k 171.51k 71.00% 1522671 requests in 10.00s, 127.79MB read Requests/sec: 152258.70 Transfer/sec: 12.78MB
目前 Hyper 基准测试已经比 TechEmpower 更有参考性,所以从结果来看,我们很兴奋 Tokio 调度器已经可以冲击这样的性能排行榜。
另外一个令人印象深刻的结果是,Tonic,流行的 gRPC 客户端/服务端框架,取得了超过10%的性能提升,这还是在 Tonic 本身没有做特定优化的情况下!
结论
我非常高兴参与这项持续数月的大工程,它将成为 Rust 异步 I/O 发展的重大事件。同时我也对最终取得的结果感到满意,当然 Tokio 中仍然有可以继续优化和性能提升的空间,这不是终点。 (编辑:威海站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|