New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat:change thread sheduling method in ThreadPool class #2648
base: unstable
Are you sure you want to change the base?
Conversation
…rting pika in centos
// 1. loop for short time | ||
for (uint32_t tries = 0; tries < 200; ++tries) { | ||
if (newest_node_.load(std::memory_order_acquire) != nullptr) { | ||
last = newest_node_.exchange(nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里先到的线程直接摘了整个链表,据为己有,在去线性消费,可能会导致延迟波动大,建议尽量将任务均匀分给线程池里的worker。毕竟Pika读写链路上都是自己的线程,和rocksdb的线程模型差异比较大(Rocksdb这块都是application线程在对每个writer并发),这一块可能得多一些考量。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
我想了一下,一次只取一定数量的 task 大概有两种办法:
1、一个 worker 对应一个无锁链表,然后新的 task 就随机或者遍历地往这些链表中加;
2、依旧使用一个无锁链表,但是无锁链表的容量较低,比如为 10 个这样的,这样保证一个 worker 一次最多取 10 个。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
第二个方法直接测试就行,第一个方法见我新的分支:https://github.com/QlQlqiqi/pika/tree/change-thread-shedule-with-mutil-list
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
我这里测的结果是这两个方法速度不相上下,当然如果调参合适的话应该会有较大的差距
The logic is based on function
WriteThread::AwaitState
in rocksdb. linkBefore:
await
. It can make the worker sleep with high probability due to intense competition. And it can cost much time to sleep and wake up.After:
2.1. 1-level. Using spin-loop to wait.
2.2. 2-level. Using long-time-loop to wait. The worker maybe yield the cpu when some condition is reached. And using a data to store probability of entering 2-level loop.
2.3. 3-level. Using function
await
to wait for new tasks.params
default:
200
. Too much number maybe cause high cpu load. Too few number maybe cause vain opration.default:
std::min(worker_num, 100)
. When the number of tasks in queue exceeds it, the main thread which call functionSchedule
callstd::this_thread::yield()
.default:
max_queue_size
. When the number of tasks in queue exceeds it, the main thread which call functionSchedule
callstd::this_thread::yield()
till the number of tasks in queue is less than threshold.default:
100
. The max time of loop in 2-level loop.default:
3
. If the time the functionstd::this_thread::yield()
spends exceeds the threshold, the data sorce may be updated.default:
3
. If the times of reaching condition above(5), the data sorce will be updated.default:
256
. It represent the provability of enter 2-level loop is not lower than1/sampling_base
.