From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 2284AA046B for ; Wed, 24 Jul 2019 15:18:10 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 01E491C1FB; Wed, 24 Jul 2019 15:18:10 +0200 (CEST) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by dpdk.org (Postfix) with ESMTP id 0AC821C1F3; Wed, 24 Jul 2019 15:18:07 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 24 Jul 2019 06:18:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,303,1559545200"; d="scan'208";a="171500943" Received: from silpixa00399952.ir.intel.com (HELO silpixa00399952.ger.corp.intel.com) ([10.237.222.88]) by fmsmga007.fm.intel.com with ESMTP; 24 Jul 2019 06:18:05 -0700 From: David Hunt To: dev@dpdk.org Cc: david.hunt@intel.com, stable@dpdk.org Date: Wed, 24 Jul 2019 14:18:03 +0100 Message-Id: <20190724131803.30066-1-david.hunt@intel.com> X-Mailer: git-send-email 2.17.1 Subject: [dpdk-dev] [PATCH v1] examples/power: fix oob frequency oscillations X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- 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