@@ -281,7 +281,7 @@ static void dirtylimit_set_throttle(CPUState *cpu,
{
int64_t ring_full_time_us = 0;
uint64_t sleep_pct = 0;
- uint64_t throttle_pct = 0;
+ double throttle_pct = 0;
uint64_t throttle_us = 0;
int64_t throtlle_us_old = cpu->throttle_us_per_full;
@@ -294,14 +294,14 @@ static void dirtylimit_set_throttle(CPUState *cpu,
if (dirtylimit_need_linear_adjustment(quota, current)) {
if (quota < current) {
- throttle_pct = (current - quota) * 100 / current;
+ throttle_pct = (current - quota) / (double)quota;
throttle_us =
- ring_full_time_us * throttle_pct / (double)(100 - throttle_pct);
+ ring_full_time_us * throttle_pct;
cpu->throttle_us_per_full += throttle_us;
} else {
- throttle_pct = (quota - current) * 100 / quota;
+ throttle_pct = (quota - current) / (double)current;
throttle_us =
- ring_full_time_us * throttle_pct / (double)(100 - throttle_pct);
+ ring_full_time_us * throttle_pct;
cpu->throttle_us_per_full -= throttle_us;
}
Using the current algorithm, there are issues with precision not being handled correctly during division operations. (Even though double type casting is used in the function, it does not seem to have any effect.) Refer to the results of the test program from [1]. When there is a large discrepancy between current and quota, there is a noticeable error. The main derivation of the new algorithm is(For current > quota): ring_full_time_us * current quota = -------------------------------- ring_full_time_us + throttle_us current - quota throttle_us = ----------------- * ring_full_time_us quota In the actual code, first calculate the value of {(current-quota})\quota} and store the intermediate result as a double. Then, multiply it by ring_full_time_us. Test scenario: - generate dirty pages program: tests/migration/stress, dirtyrate is about 1500MB/s with WP enable. - dirtyring size : 65536 - dirtylimit: 333 To facilitate testing, merge both the new and old algorithms into the same code, calculate the difference in throttle_us between them, and track the value of the next non-linear adjustment after a linear adjustment. The test results are as follows: - throttle_us difference: [19003, 24755, 25231, 14630, 25705] average: 21864 - next non-linear adjustment": [16764, 16368, 16357, 16591, 16347] average: 16485 Based on the test results, after merging this patch, the linear adjustment value will increase, allowing the quota to be reached one loop earlier. [1]: https://github.com/cai-fuqiang/kernel_test/tree/master/dirty_throttle_pct_test Signed-off-by: wangfuqiang49 <wangfuqiang49@jd.com> --- system/dirtylimit.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)