patches for DPDK stable branches
 help / color / mirror / Atom feed
* [dpdk-stable] [PATCH v1] examples/power: fix oob frequency oscillations
@ 2019-07-24 13:18 David Hunt
  2019-07-26 10:15 ` [dpdk-stable] [dpdk-dev] " Burakov, Anatoly
  2019-11-12  7:23 ` [dpdk-stable] " Thomas Monjalon
  0 siblings, 2 replies; 4+ messages in thread
From: David Hunt @ 2019-07-24 13:18 UTC (permalink / raw)
  To: dev; +Cc: david.hunt, stable

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


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-11-12  7:24 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-24 13:18 [dpdk-stable] [PATCH v1] examples/power: fix oob frequency oscillations David Hunt
2019-07-26 10:15 ` [dpdk-stable] [dpdk-dev] " Burakov, Anatoly
2019-08-06 11:18   ` Thomas Monjalon
2019-11-12  7:23 ` [dpdk-stable] " Thomas Monjalon

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).