一些关于并行任务调度的实验
最近在自己的4核机器上跑数据,要在12组8000+个照片中找到人脸。为了加速进度开4核以组为单位在进程级别并行处理。考虑到进程的频繁调度可能会浪费时间,所以写了个简单的调度程序。大体思路是维持有4个工作进程在跑,每跑完一个就启动下一个这样。跑完了看下结果是7分钟。
但想看一下这个东西对工作是不是真的有用(evaluation,职业病啊)。所以直接开12个进程跑啊跑,结果发现还是7分钟。悲剧啊。
然后又做了一个小实验,写了个空循环的程序,跑一遍大概要16.5秒。然后用之前写的调度程序跑需要83.3秒,直接同时启动20个进程需要82.7秒。又悲剧了。
后来想了一下,跑一遍需要16.5秒,在4核电脑上跑20遍的理论值就是82.5秒,所以Windows的进程调度(及其他因素)其实只浪费了约0.2%的时间。也就是说,我的程序就算写的极其精巧,有完美的效果,也只不过能将性能提升0.2%,进程调度根本就不是性能的瓶颈。又遭到了Knuth那句经典名言的报应:premature optimization is the root ofall evil. 浪费了开发时间,结果反而拖慢了性能。
至于我的程序反而更慢,可能是因为没有指定这个进程就一定要在这个核上跑,因此并没有避免进程调度的影响。同时这个程序还引入了其他载荷,因而就显得更慢了。
所以结论就是,对于计算密集型的任务只要内存允许,可以直接全部启动让OS去慢慢调度。我的这个程序也许只在限制内存方面可能有用了。至于I/O密集型的任务,在机械硬盘上还是避免并发执行的好,毕竟磁头来回移动时需要时间的。这个在平时拷贝文件的时候也有实际体会。