diff mbox series

[2/2] improve precision of throttle_pct

Message ID 1735610174-37467-3-git-send-email-fuqiang.wng@gmail.com (mailing list archive)
State New
Headers show
Series some optimize in dirtylimit_throttle_pct | expand

Commit Message

fuqiang wang Dec. 31, 2024, 1:56 a.m. UTC
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(-)
diff mbox series

Patch

diff --git a/system/dirtylimit.c b/system/dirtylimit.c
index c7f663e5b9..25439e8e99 100644
--- a/system/dirtylimit.c
+++ b/system/dirtylimit.c
@@ -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;
         }