calculate appropriate level 0 chance #35
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
Currently the maximum level 0 chance is 0.98. Sometimes we still fail to achieve our target even with this maximum value. For example, if we have plenty of tasks of all levels to run and the average time spent in handling a level 0 task once is 50us while the average time spent in handling other tasks once is 1500us. We can calculate the final time proportion of level 0 is (50 * 0.98) / (50 * 0.98 + 1500 * 0.02) = 0.62, which is far lower than we expected.
Solution
Firstly, this PR raises the maximum level 0 chance to 0.9999, which should suffice in most cases. And the way we adjust the chance is improved. The new chance is now calculated based on the assumption that we have plenty of tasks in all levels. (It is OK when the assumption is false because then we actually don't need to balance tasks of different levels.
Formula
Say the average time spent in handling level 1 and 2 tasks once is k times of that for level 0 task, the current time proportion of level 0 tasks is m, the target proportion is m0 and the chance of level 0 tasks is p. We want to get an appropriate new chance of level 0 tasks, p'.
So, we have simultaneous equations below:
p/(p+k(1-p)) = m
p'/(p'+k(1-p')) = m0
Solving the equations we can get p' = m0(1-m)p/(m0(1-m0)-(m-m0)(p-(1-m0))).
In our implementation, we ensure 0 < p < 1, 0 <= m <= 1, 0 < m0 < 1. The denominator can be proved to be greater than zero so we needn't check it in our code.