diff options
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H')
-rw-r--r-- | src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H | 164 |
1 files changed, 113 insertions, 51 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H index 3259608ce..876e277a3 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H @@ -46,9 +46,12 @@ enum throttle_const : size_t { // Dram data bus utilization is bus utilization / 4 DRAM_BUS_UTILS = 4, + //10000 to convert to and from c% UTIL_CONVERSION = 10000, PERCENT_CONVERSION = 100, - MIN_UTIL = 1, + + //MIN_UTIL and IDLE_UTIL are in c% + MIN_UTIL = 100, IDLE_UTIL = 0, }; /// @@ -58,25 +61,47 @@ enum throttle_const : size_t class throttle { private: + /// + /// @brief Calculate the power (cW) of inputs and the power curve + /// @tparam T + /// @param[in] i_util the databus utilization that the power will be based on + /// @param[in] l_pos the dimm position for the power value being calculated. + /// @return Integral type T + /// + template<typename T> + inline T calc_power (const T i_util, const size_t i_pos) + { + return ((i_util / UTIL_CONVERSION) * iv_pwr_slope[i_pos]) + iv_pwr_int[i_pos]; + } + + /// + /// @brief Raise the o_value by the percent passed in + /// @param[in] i_uplift the percent the o_Value should be raised by + /// @param[out] o_value the value that will be modified + /// + inline void calc_power_uplift (const uint8_t i_uplift, double& o_value) + { + o_value *= (1 + (double(i_uplift) / PERCENT_CONVERSION)); + } public: const fapi2::Target<fapi2::TARGET_TYPE_MCA>& iv_target; //dimm level uint32_t iv_databus_port_max; + //TK change thermal limit as well as power curves uint8_t iv_power_uplift_idle; uint8_t iv_power_uplift; - uint32_t iv_runtime_n_slot; - uint32_t iv_runtime_n_port; + uint16_t iv_runtime_n_slot; + uint16_t iv_runtime_n_port; uint32_t iv_m_clocks; uint32_t iv_dimm_thermal_limit[MAX_DIMM_PER_PORT] = {}; uint16_t iv_pwr_slope[MAX_DIMM_PER_PORT] = {}; uint16_t iv_pwr_int[MAX_DIMM_PER_PORT] = {}; - uint32_t iv_n_slot; - uint32_t iv_n_port; + uint16_t iv_n_slot; + uint16_t iv_n_port; uint32_t iv_port_power_limit; - uint32_t iv_port_maxpower; uint32_t iv_calc_port_maxpower; //default ctor deleted @@ -95,71 +120,82 @@ class throttle ~throttle() = default; /// - /// @brief Calculates the min and max power usage for a port based off of power curves and utilizati + /// @brief Calculates the min and max power usage for a port /// @param[in] i_idle_util the utilization of the databus in idle mode /// @param[in] i_max_util the utilization of the port at maximum possible (mrw or calculated) /// @param[out] o_port_power_idle max value of port power in cW /// @param[out] o_port_power_max max value of port power in cW /// @note Called twice in p9_mss_bulk_pwr_throttles - /// @note uses dimm power curves from class variables - /// - void calc_port_power(const double i_idle_util [MAX_DIMM_PER_PORT], - const double i_max_util [MAX_DIMM_PER_PORT], - double& o_port_power_idle, - double& o_port_power_max); - /// - /// @brief Calculate the port power curve in order to calculate the port utilization - /// @paramp[in] i_port_power_calc_idle double of the port's power consumption at idle - /// @paramp[in] i_port_power_calc_max double of the port's power consumption at max utilization - /// @paramp[out] o_port_power_slope - /// @paramp[out] o_port_power_int - /// @return FAPI2_RC_SUCCESS iff success + /// + void calc_port_power( const double i_idle_util [MAX_DIMM_PER_PORT], + const double i_max_util [MAX_DIMM_PER_PORT], + double& o_port_power_idle, + double& o_port_power_max); + /// + /// @brief Calculates max and min power usages based off of DIMM power curves + /// @param[in] i_databus_port_max max databus utilization for the port (either calculated or mrw) + /// @param[in] i_port_power_calc_idle double of the port's power consumption at idle + /// @param[out] o_dimm_power_idle array of dimm power in cW + /// @param[out] o_dimm_power_max array of dimm power in cW /// @note Called in p9_mss_bulk_pwr_throttles - /// @note Port power curve needed to calculate the port utilization + /// @note used for the thermal throttles /// - fapi2::ReturnCode calc_port_power_curve(const double& i_port_power_calc_idle, - const double& i_port_power_calc_max, - uint32_t& o_port_power_slope, - uint32_t& o_port_power_int); + void calc_dimm_power(const double i_databus_idle, + const double i_databus_max, + double o_dimm_power_idle [MAX_DIMM_PER_PORT], + double o_dimm_power_max [MAX_DIMM_PER_PORT]); + /// - /// @brief Calculate the port's databus utilization given the port's power curve - /// @paramp[in] i_port_power_slope - /// @paramp[in] i_port_power_int - /// @paramp[out] o_port_util the port's databus utilization + /// @brief Calculate the power curve in order to calculate databus utilization + /// @param[in] i_power_idle double of the port's power consumption at idle + /// @param[in] i_power_max double of the port's power consumption at max utilization + /// @param[out] o_power_slope + /// @param[out] o_power_int + /// @note Called in p9_mss_bulk_pwr_throttles + /// @note Power curve needed to calculate the utilization + /// + fapi2::ReturnCode calc_power_curve(const double i_power_idle, + const double i_power_max, + uint32_t& o_power_slope, + uint32_t& o_power_int); + /// + /// @brief Calculate the databus utilization given the power curve + /// @param[in] i_slope + /// @param[in] i_int + /// @param[in] i_power_limit either iv_port_power_limit or thermal_power_limit depending on throttle type + /// @param[out] o_port_util the port's databus utilization /// @note Called in p9_mss_bulk_pwr_throttles /// @note Chooses worst case between the maximum allowed databus utilization and the calculated value - /// @notes makes sure that the utilization isn't 0 /// - void calc_port_util_usage(const uint32_t& i_port_power_slope, - const uint32_t& i_port_power_int, - double& o_port_util); - + void calc_util_usage(const uint32_t i_slope, + const uint32_t i_int, + const uint32_t i_power_limit, + double& o_util); /// - /// @brief Calculates the power max and idle for each dimm using power curves and databus utilization - /// @param[out] o_dimm_power_idle double type for precision, the DIMM power limit in idle state (0 utilization) - /// @param[out] o_dimm_power_max double type for precision, the DIMM power limit at max utilization - /// @note Called in p9_mss_bulk_pwr_throttle for thermal_throttles, eff_config_thermal - /// @note power values are as if dimm is alone on port, using port_databus_util_max + ///@brief calculated the output power estimate from the calculated N throttle + ///@param[in] i_n_port is the throtte N (address operations) that the power (cW) is be calculated from + ///@return the power calculated from the uint /// - void calc_dimm_power(double o_dimm_power_idle [MAX_DIMM_PER_PORT], - double o_dimm_power_max [MAX_DIMM_PER_PORT]); + uint32_t calc_power_from_n (const uint16_t i_n_port); + /// - /// @brief Converts the port maximum databus to a dimm level based on powerslopes and dimms installed + /// @brief Converts the port maximum databus util to a dimm level based on powerslopes and dimms installed /// @param[in] i_databus_port_max max databus utilization for the port (either calculated or mrw) /// @param[out] o_databus_dimm_max array of dimm utilization values /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK /// @note Called in p9_mss_bulk_pwr_throttles /// @used to calculate the port power based off of DIMM power curves /// - fapi2::ReturnCode calc_databus(const double& i_databus_port_max, - double o_databus_dimm_max [MAX_DIMM_PER_PORT]); + fapi2::ReturnCode calc_databus( const double i_databus_port_max, + double o_databus_dimm_max [MAX_DIMM_PER_PORT]); /// - /// @brief Set ATTR_MSS_CHANNEL_PAIR_MAXPOWER and ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, + /// @brief Calculate ATTR_MSS_CHANNEL_PAIR_MAXPOWER and ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK /// @note Called in p9_mss_bulk_pwr_throttles - /// @note determines the throttle levels based off of the port's power curve, - /// sets the slot throttles to the same + /// @note determines the throttle levels based off of the port's power curve, max databus utilization, + /// and memwat target. + /// @note currently sets the slot and port throttles to the same value /// fapi2::ReturnCode power_regulator_throttles (); @@ -179,15 +215,16 @@ class throttle /// @param[in] i_num_dram_clocks window of M DRAM clocks /// @return number of throttled commands allowed /// @note Uses N/M Throttling. -/// Equation: (DRAM data bus utilization Percent / 10000 ) = ((N * M) / 4 ) -/// Equation: N = (DRAM data bus utilization Percent * M) / (4 * 10000) +/// Equation: N = (DRAM data bus utilization * M) / (4 * 10000) +/// inline uint32_t throttled_cmds(const uint32_t i_databus_util, const uint32_t i_num_dram_clocks) { constexpr uint64_t l_divisor = DRAM_BUS_UTILS * UTIL_CONVERSION; const uint64_t l_dividend = i_databus_util * i_num_dram_clocks; const uint64_t l_result = l_dividend / l_divisor; - return l_result; + //Make sure N is not equal to 0, or we brick the dram until reboot + return ((l_result == 0) ? 1 : l_result); } /// @@ -196,7 +233,7 @@ inline uint32_t throttled_cmds(const uint32_t i_databus_util, const uint32_t i_n /// @param[in] i_num_dram_clocks window of M DRAM clocks /// @return number of throttled commands allowed /// @note Uses N/M Throttling. -/// Equation: databus utilization = (N * 4 * 100000) / M +/// @note DRAM databus utilization = N * 4 * 10000 / M /// inline double calc_util_from_throttles(const uint16_t i_n_throttles, const uint32_t i_num_dram_clocks) { @@ -206,12 +243,37 @@ inline double calc_util_from_throttles(const uint16_t i_n_throttles, const uint3 } /// +/// @brief Determines if the double has decimal digits and adds 1 and rounds if true +/// @param[in] io_val the double to be rounded up if trialing digits +/// @return the input value rounded up to the next whole digit +/// @note Called in p9_mss_bulk_pwr_throttles +/// +inline uint32_t round_up(double i_val) +{ + //convert to uint to truncate decimals and convert back to double for comparison + uint32_t temp = uint32_t (i_val); + + //if not equal, lost something from truncating, so add 1 + temp += (temp == i_val) ? 0 : 1; + + //Truncate final value + return temp; +} + +/// /// @brief Perform thermal calculations as part of the effective configuration /// @param[in] i_target the MCS target in which the runtime throttles will be reset /// @return FAPI2_RC_SUCCESS iff ok /// fapi2::ReturnCode restore_runtime_throttles( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target ); +/// +/// @brief Update the runtime throttles to the worst case of the general throttle values and the runtime values +/// @param[in] i_target the MCS target in which the runtime throttles will be set +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode update_runtime_throttles(const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >& i_targets); + }//power_thermal }// mss |