Jade
Jade
据我观察,频繁的触发 futex_wake 和 futex_wait 的原因是因为整个系统在“不必要”的时机进入的休眠状态,这样很容易产生一个 wake 和 多个 wait,导致系统调用频繁,worker 越多,wait 和 wake 越频繁,所以减少如何减少这种“不必要性”才是最重要的。我这边经过大量的测试发现一个 case 就是整个系统在高压繁忙下也进入了 wait 状态,很明显这是“不合适的”,“不必要的”。这是由于当前的模型下,会导致 epoll 延后处理,形成了多个 worker 工作在一个 queue 上,queue 没有了,立刻都进入休眠,然后 epoll 被唤醒后,“worker 们”又相继被唤醒,造成了”不必要性“。
> > 据我观察,频繁的触发 futex_wake 和 futex_wait 的原因是因为整个系统在“不必要”的时机进入的休眠状态,这样很容易产生一个 wake 和 多个 wait,导致系统调用频繁,worker 越多,wait 和 wake 越频繁,所以减少如何减少这种“不必要性”才是最重要的。我这边经过大量的测试发现一个 case 就是整个系统在高压繁忙下也进入了 wait 状态,很明显这是“不合适的”,“不必要的”。这是由于当前的模型下,会导致 epoll 延后处理,形成了多个 worker 工作在一个 queue 上,queue 没有了,立刻都进入休眠,然后 epoll 被唤醒后,“worker 们”又相继被唤醒,造成了”不必要性“。 >...
> 类似go的 steal half是不是更好一些 steal 多个的时候,在流量不高的情况下,会造成同一个任务被两个 pthread 反复偷的情况,A 偷了 10 个,做到 一半,可能又被 B 偷回去了。而且由于任务的执行时间长短不同,一刀切的偷多个,可能导致 steal成本增加。
找到一个合适的 batch 是很难的,因为任务本身可能有大有小,即使 steal 了合适的 batch,也不能保证是均匀做完的。 我的思路是其实这和一个流批的系统很像,可以把**原来看作流,现在想做成批处理**,对于不同的业务落地场景,肯定是不同的 batch 会更好,所以可以把这个 batch 设计成可变的,默认大小是 **_rq.size() / NUM_WORKER**。