cpu高 rust腐蚀"/>
cpu高 rust腐蚀
使用rust tokio Interval作为定时器,可能会在系统休眠或进程挂起恢复后,CPU爆满,甚至导致死机,Windows、iOS、Android都有这个问题。
引言
虽然rust代码写得不多,但使用C++的性能分析方法论和工具链,也能分析rust代码的性能。这次,就是通过WPT(Windows Performance Tools)和Instruments分析了rust的第三方库tokio的Interval的一个性能问题。
问题的发现
在Win10系统(CPU 12核)休眠恢复之后,发现rust进程的CPU占比超过6%,相当于1个CPU核的70%。于是,赶紧用WPT抓了一个现场。通过WPT分析,发现CPU主要被其中一个线程消耗。
其他平台的测试验证
由于rust代码是跨平台的SDK,因此,也需要验证下其他平台是否有同样的问题。
iOS
使用Instruments抓了iOS与Windows类似场景,消耗CPU最多的也是这个线程。
Mac
经过反复测试,未发现Mac有这个问题。
Android
经过反复测试,未发现Android有这个问题。(后来发现,是因为Android连上电脑是充电模式,进程不会自动挂起,没有进入到可复现这个问题的路径。)
tokio的Interval的Demo实验
经过多平台的测试验证,发现Windows和iOS有这个问题,但是Mac没有发现这个问题,这就感觉到很迷糊了。通过WPT和Instruments的分析数据,已定位到相关代码,使用tokio的Interval运行一个定时任务,每隔1S执行1次。其中,tokio版本0.1.13。排查了自有代码,没有找到可能引起这个问题的代码。经过现象分析,推测可能跟tokio有关,于是,写了一个简化的Demo进行验证。
实验代码说明
创建一个循环定时器任务,每隔1S运行1次。在每次定时器任务触发时,输出以下调试信息:当前任务的序号
任务触发的绝对时间
Instant::now()获取的时间
当前任务的到期时间
pubfn test_interval(){letinterval=Duration::from_millis(1000);lettask=Interval::new_interval(interval).for_each(move|deadline|{letcount={letmutcount=TIME_COUNT.write().unwrap();*count+=1;*count};println!("{}, {}, now: {:?}, deadline: {:?}",count,Utc::now().format("%T"),Instant::now(),deadline);Ok(())}).then(|_|{Ok(())});MY_RUNTIME.executor().spawn(task);}
系统休眠实验
由于Windows平台发现的问题,就是通过系统休眠的方式来发现的,因此,对Windows、Mac、Linux都进行了系统休眠实验。
实验方法:先让系统休眠一段时间(超过2分钟),然后重新激活系统,观察激活后的任务执行次数。如果系统重新激活后1S内,任务执行次数只有1-3次,属于没有问题;如果有大量任务执行,则是有问题的。
Windows系统休眠实验结果系统开始休眠时间:14:08:33。
激活系统时间:14:15:05。
系统激活后1S内,执行任务394次,存在问题。1, 14:08:18, now: Instant { t: 1287693.9087257s }, deadline: Instant { t: 1287693.9079829s }
2, 14:08:19,
更多推荐
cpu高 rust腐蚀
发布评论