From: David Hunt <david.hunt@intel.com>
To: dev@dpdk.org
Cc: david.hunt@intel.com, stable@dpdk.org
Subject: [dpdk-dev] [PATCH v1] examples/power: fix oob frequency oscillations
Date: Wed, 24 Jul 2019 14:18:03 +0100 [thread overview]
Message-ID: <20190724131803.30066-1-david.hunt@intel.com> (raw)
The branch ratio algorithm in the vm_power_manager sample application
can be very sensitive at patricular loads in a workload, causing
oscillations between min and max frequency. For example, if a
workload is at 50%, scaling up may change the ratio
enough that it immediately thinks it needs to scale down again.
This patch introduces a sliding window recording the scale up/down
direction for the last 32 samples, and scales up if any samples indicate
we should scale up, otherwise scale down. Each core has it's own window.
Fixes: 4b1a631b8a8a ("examples/vm_power: add oob monitoring functions")
Cc: stable@dpdk.org
Signed-off-by: David Hunt <david.hunt@intel.com>
---
examples/vm_power_manager/oob_monitor_x86.c | 34 +++++++++++++++++++--
examples/vm_power_manager/power_manager.c | 3 +-
examples/vm_power_manager/power_manager.h | 12 ++++++++
3 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/examples/vm_power_manager/oob_monitor_x86.c b/examples/vm_power_manager/oob_monitor_x86.c
index ebd96b205..aecfcb2eb 100644
--- a/examples/vm_power_manager/oob_monitor_x86.c
+++ b/examples/vm_power_manager/oob_monitor_x86.c
@@ -39,6 +39,7 @@ apply_policy(int core)
int64_t hits_diff, miss_diff;
float ratio;
int ret;
+ int freq_window_idx, up_count = 0, i;
g_active = 0;
ci = get_core_info();
@@ -101,10 +102,37 @@ apply_policy(int core)
ratio = (float)miss_diff * (float)100 / (float)hits_diff;
- if (ratio < ci->branch_ratio_threshold)
- power_manager_scale_core_min(core);
+ /*
+ * Store the last few directions that the ratio indicates
+ * we should take. If there's on 'up', then we scale up
+ * quickly. If all indicate 'down', only then do we scale
+ * down. Each core_details struct has it's own array.
+ */
+ freq_window_idx = ci->cd[core].freq_window_idx;
+ if (ratio > ci->branch_ratio_threshold)
+ ci->cd[core].freq_directions[freq_window_idx] = 1;
else
- power_manager_scale_core_max(core);
+ ci->cd[core].freq_directions[freq_window_idx] = 0;
+
+ freq_window_idx++;
+ freq_window_idx = freq_window_idx & (FREQ_WINDOW_SIZE-1);
+ ci->cd[core].freq_window_idx = freq_window_idx;
+
+ up_count = 0;
+ for (i = 0; i < FREQ_WINDOW_SIZE; i++)
+ up_count += ci->cd[core].freq_directions[i];
+
+ if (up_count == 0) {
+ if (ci->cd[core].freq_state != FREQ_MIN) {
+ power_manager_scale_core_min(core);
+ ci->cd[core].freq_state = FREQ_MIN;
+ }
+ } else {
+ if (ci->cd[core].freq_state != FREQ_MAX) {
+ power_manager_scale_core_max(core);
+ ci->cd[core].freq_state = FREQ_MAX;
+ }
+ }
g_active = 1;
return ratio;
diff --git a/examples/vm_power_manager/power_manager.c b/examples/vm_power_manager/power_manager.c
index 9d4e587b0..7b4f4b3c4 100644
--- a/examples/vm_power_manager/power_manager.c
+++ b/examples/vm_power_manager/power_manager.c
@@ -62,14 +62,13 @@ core_info_init(void)
ci->core_count = get_nprocs_conf();
ci->branch_ratio_threshold = BRANCH_RATIO_THRESHOLD;
ci->cd = malloc(ci->core_count * sizeof(struct core_details));
+ memset(ci->cd, 0, ci->core_count * sizeof(struct core_details));
if (!ci->cd) {
RTE_LOG(ERR, POWER_MANAGER, "Failed to allocate memory for core info.");
return -1;
}
for (i = 0; i < ci->core_count; i++) {
ci->cd[i].global_enabled_cpus = 1;
- ci->cd[i].oob_enabled = 0;
- ci->cd[i].msr_fd = 0;
}
printf("%d cores in system\n", ci->core_count);
return 0;
diff --git a/examples/vm_power_manager/power_manager.h b/examples/vm_power_manager/power_manager.h
index e81a60ae5..e324766b6 100644
--- a/examples/vm_power_manager/power_manager.h
+++ b/examples/vm_power_manager/power_manager.h
@@ -8,12 +8,24 @@
#ifdef __cplusplus
extern "C" {
#endif
+
+#define FREQ_WINDOW_SIZE 32
+
+enum {
+ FREQ_UNKNOWN,
+ FREQ_MIN,
+ FREQ_MAX
+};
+
struct core_details {
uint64_t last_branches;
uint64_t last_branch_misses;
uint16_t global_enabled_cpus;
uint16_t oob_enabled;
int msr_fd;
+ uint16_t freq_directions[FREQ_WINDOW_SIZE];
+ uint16_t freq_window_idx;
+ uint16_t freq_state;
};
struct core_info {
--
2.17.1
next reply other threads:[~2019-07-24 13:18 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-24 13:18 David Hunt [this message]
2019-07-26 10:15 ` Burakov, Anatoly
2019-08-06 11:18 ` Thomas Monjalon
2019-10-27 18:35 ` Thomas Monjalon
2019-10-29 14:05 ` Hunt, David
2019-11-01 23:00 ` Thomas Monjalon
2019-11-04 10:16 ` Burakov, Anatoly
2019-11-12 7:23 ` [dpdk-dev] [dpdk-stable] " Thomas Monjalon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190724131803.30066-1-david.hunt@intel.com \
--to=david.hunt@intel.com \
--cc=dev@dpdk.org \
--cc=stable@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).