现象:在n个物理核的机器上跑线程数为c(小于n)的多线程程序,其对串行版本的加速比达不到c
(持续完善ing,目前只有“全内存,计算intensive”类程序的经验)
原因排查:
- 看cpu占用是否达到线性加速:
top
或htop
:看是否达到串行时的cpu占用率*c
(top中程序的cpu占用是把每个线程的cpu占用累加起来的)htop
可以更加直观地看到每个逻辑核的占用情况
- 达不到的可能原因:
- 环境:系统有其他进程在跑(实际经验表明,不同时候在同一台机器上跑性能差距可能相差达到3倍)
- IO等待
- 达到了, 但是加速比明显没有c(比如30线程,加速比是10),可能原因:
- 程序逻辑是否存在忙等
- 看程序逻辑层面的时间占用:
perf
火焰图,看哪些处理时间占比大- 程序逻辑层面的线程竞争,如加锁和解锁
- 如果加锁和解锁的时间占到50%,那加速比应该最多只有c/2
- IO竞争
- 和串行版本的IO时间占比对比
- 说明:若不同线程等待的IO资源是相互独立的(即没有相互等待,相互等待比如要写同一个资源),则IO等待不是多线程程序无法线性加速的原因(此时IO等待对运行时间的贡献和没有竞争的计算类似了)(多说一句,对于线程数多于物理核数的情况,会出现这样的图景:某个核上的线程进入等待IO时,这个核上可以切换成另一个线程来执行)
- 程序逻辑层面的线程竞争,如加锁和解锁
- 看系统底层执行的情况:
- 看上下文切换:
vmstat
,vmstat 1 10
每个1秒统计一次,总共统计10次;关注cs
列- 上下文切换发生在:线程切换,系统调用等
- 看缓存竞争
- 看上下文切换: