From 1fdf576ec73f676c1bfa2e2524293deab0f5cd68 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Fri, 17 Aug 2018 10:17:59 +0100 Subject: [PATCH] mem: Implement QoS Proportional Fair policy Providing a configurable fair scheduling policy based on utilization; utilization is directly proportional to a score which is inversely proportional to the QoS priority. It is meant to avoid starvation of low priority packets. Users can tune the policy by adjusting the weight parameter (weight of the following formula) new_score = ((1.0 - weight) * old_score) + (weight * served_bytes) Change-Id: I7679e234b916c57ebed06cec0ff3cff3cf2aef22 Signed-off-by: Giacomo Travaglini Reviewed-on: https://gem5-review.googlesource.com/12359 Reviewed-by: Daniel Carvalho Reviewed-by: Anthony Gutierrez Maintainer: Anthony Gutierrez --- src/mem/qos/QoSPolicy.py | 35 +++++++++++ src/mem/qos/SConscript | 1 + src/mem/qos/policy_pf.cc | 130 +++++++++++++++++++++++++++++++++++++++ src/mem/qos/policy_pf.hh | 117 +++++++++++++++++++++++++++++++++++ 4 files changed, 283 insertions(+) create mode 100644 src/mem/qos/policy_pf.cc create mode 100644 src/mem/qos/policy_pf.hh diff --git a/src/mem/qos/QoSPolicy.py b/src/mem/qos/QoSPolicy.py index 9ccd98562..6db04aca1 100644 --- a/src/mem/qos/QoSPolicy.py +++ b/src/mem/qos/QoSPolicy.py @@ -81,3 +81,38 @@ class QoSFixedPriorityPolicy(QoSPolicy): # default fixed priority value for non-listed Masters qos_fixed_prio_default_prio = Param.UInt8(0, "Default priority for non-listed Masters") + +class QoSPropFairPolicy(QoSPolicy): + type = 'QoSPropFairPolicy' + cxx_header = "mem/qos/policy_pf.hh" + cxx_class = 'QoS::PropFairPolicy' + + cxx_exports = [ + PyBindMethod('initMasterName'), + PyBindMethod('initMasterObj'), + ] + + _mscores = None + + def setInitialScore(self, master, score): + if not self._mscores: + self._mscores = [] + + self._mscores.append([master, score]) + + def init(self): + if not self._mscores: + print("Error, use setInitialScore to init masters/scores\n"); + exit(1) + else: + for mprio in self._mscores: + master = mprio[0] + score = mprio[1] + if isinstance(master, basestring): + self.getCCObject().initMasterName( + master, float(score)) + else: + self.getCCObject().initMasterObj( + master.getCCObject(), float(score)) + + weight = Param.Float(0.5, "Pf score weight") diff --git a/src/mem/qos/SConscript b/src/mem/qos/SConscript index 23351ca4f..7c895cead 100644 --- a/src/mem/qos/SConscript +++ b/src/mem/qos/SConscript @@ -44,6 +44,7 @@ SimObject('QoSTurnaround.py') Source('policy.cc') Source('policy_fixed_prio.cc') +Source('policy_pf.cc') Source('turnaround_policy_ideal.cc') Source('q_policy.cc') Source('mem_ctrl.cc') diff --git a/src/mem/qos/policy_pf.cc b/src/mem/qos/policy_pf.cc new file mode 100644 index 000000000..58c4e3896 --- /dev/null +++ b/src/mem/qos/policy_pf.cc @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2018 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Giacomo Travaglini + */ + +#include "mem/qos/policy_pf.hh" + +#include "mem/request.hh" + +namespace QoS { + +PropFairPolicy::PropFairPolicy(const Params* p) + : Policy(p), weight(p->weight) +{ + fatal_if(weight < 0 || weight > 1, + "weight must be a value between 0 and 1"); +} + +PropFairPolicy::~PropFairPolicy() +{} + +template +void +PropFairPolicy::initMaster(const Master master, const double score) +{ + MasterID m_id = memCtrl->system()->lookupMasterId(master); + + assert(m_id != Request::invldMasterId); + + // Setting the Initial score for the selected master. + history.push_back(std::make_pair(m_id, score)); + + fatal_if(history.size() > memCtrl->numPriorities(), + "Policy's maximum number of masters is currently dictated " + "by the maximum number of priorities\n"); +} + +void +PropFairPolicy::initMasterName(const std::string master, const double score) +{ + initMaster(master, score); +} + +void +PropFairPolicy::initMasterObj(const SimObject* master, const double score) +{ + initMaster(master, score); +} + +double +PropFairPolicy::updateScore( + const double old_score, const uint64_t served_bytes) const +{ + return ((1.0 - weight) * old_score) + (weight * served_bytes); +} + +uint8_t +PropFairPolicy::schedule(const MasterID pkt_mid, const uint64_t pkt_size) +{ + auto sort_pred = + [] (const MasterHistory& lhs, const MasterHistory& rhs) + { return lhs.second > rhs.second; }; + + // Sorting in reverse in base of personal history: + // First elements have higher history/score -> lower priority. + // The qos priority is the position in the sorted vector. + std::sort(history.begin(), history.end(), sort_pred); + + const double served_bytes = static_cast(pkt_size); + + uint8_t pkt_priority = 0; + for (auto m_hist = history.begin(); m_hist != history.end(); m_hist++) { + + MasterID curr_mid = m_hist->first; + double& curr_score = m_hist->second; + + if (curr_mid == pkt_mid) { + // The qos priority is the position in the sorted vector. + pkt_priority = std::distance(history.begin(), m_hist); + + curr_score = updateScore(curr_score, served_bytes); + } else { + curr_score = updateScore(curr_score, 0); + } + } + + return pkt_priority; +} + +} // namespace QoS + +QoS::PropFairPolicy * +QoSPropFairPolicyParams::create() +{ + return new QoS::PropFairPolicy(this); +} diff --git a/src/mem/qos/policy_pf.hh b/src/mem/qos/policy_pf.hh new file mode 100644 index 000000000..c741e9ca7 --- /dev/null +++ b/src/mem/qos/policy_pf.hh @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2018 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Giacomo Travaglini + */ + +#ifndef __MEM_QOS_POLICY_PF_HH__ +#define __MEM_QOS_POLICY_PF_HH__ + +#include "mem/qos/policy.hh" +#include "params/QoSPropFairPolicy.hh" + +namespace QoS { + +/** + * Proportional Fair QoS Policy + * Providing a configurable fair scheduling policy based on + * utilization; utilization is directly proportional to a + * score which is inversely proportional to the QoS priority + * Users can tune the policy by adjusting the weight parameter + * (weight of the formula) + * + * This is the formula used by the policy + * ((1.0 - weight) * old_score) + (weight * served_bytes); + */ +class PropFairPolicy : public Policy +{ + using Params = QoSPropFairPolicyParams; + const Params *params() const + { return static_cast(_params); } + + public: + PropFairPolicy(const Params*); + virtual ~PropFairPolicy(); + + /** + * Initialize the master's score by providing + * the master's name and initial score value. + * The master's name has to match a name in the system. + * + * @param master master's name to lookup. + * @param score initial score value for the master + */ + void initMasterName(const std::string master, const double score); + + /** + * Initialize the master's score by providing + * the master's SimObject pointer and initial score value. + * The master's pointer has to match a master in the system. + * + * @param master master's SimObject pointer to lookup. + * @param score initial score value for the master + */ + void initMasterObj(const SimObject* master, const double score); + + /** + * Schedules a packet based on proportional fair configuration + * + * @param m_id master id to schedule + * @param pkt_size size of the packet + * @return QoS priority value + */ + virtual uint8_t + schedule(const MasterID m_id, const uint64_t pkt_size) override; + + protected: + template + void initMaster(const Master master, const double score); + + inline double + updateScore(const double old_score, const uint64_t served_bytes) const; + + protected: + /** PF Policy weight */ + const double weight; + + /** history is keeping track of every master's score */ + using MasterHistory = std::pair; + std::vector history; +}; + +} // namespace QoS + +#endif // __MEM_QOS_POLICY_PF_HH__ -- 2.30.2