linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC/RFT][PATCH] cpufreq: intel_pstate: Proportional algorithm for Atom
@ 2016-10-02 17:03 Rafael J. Wysocki
  2016-10-05 13:14 ` [RFC/RFT][PATCH v2] " Rafael J. Wysocki
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Rafael J. Wysocki @ 2016-10-02 17:03 UTC (permalink / raw)
  To: Srinivas Pandruvada, Linux PM list
  Cc: Linux Kernel Mailing List, Doug Smythies

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

The PID algorithm used by the intel_pstate driver tends to drive
performance down too fast for lighter workloads, so replace it
with a modified "proportional" algorithm on Atom.

The new algorithm will set the new P-state to be 1.25 times the
available maximum times the (frequency-invariant) utilization during
the previous sampling period except when that utilization is lower
than the average performance ratio during the previous sampling
period.  In the latter case, it will increase the utilization by
50% of the difference between it and the performance ratio before
computing the target P-state to prevent performance from dropping
down too fast in some cases.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/cpufreq/intel_pstate.c |   28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -1231,9 +1231,10 @@ static inline int32_t get_avg_pstate(str
 static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu)
 {
 	struct sample *sample = &cpu->sample;
-	int32_t busy_frac, boost;
+	int32_t busy_frac, boost, avg_perf;
+	int target;
 
-	busy_frac = div_fp(sample->mperf, sample->tsc);
+	busy_frac = div_ext_fp(sample->mperf, sample->tsc);
 
 	boost = cpu->iowait_boost;
 	cpu->iowait_boost >>= 1;
@@ -1241,8 +1242,23 @@ static inline int32_t get_target_pstate_
 	if (busy_frac < boost)
 		busy_frac = boost;
 
-	sample->busy_scaled = busy_frac * 100;
-	return get_avg_pstate(cpu) - pid_calc(&cpu->pid, sample->busy_scaled);
+	/*
+	 * If the relative average performance ratio during the previous cycle
+	 * was higher than the current utilization, add 50% of the difference to
+	 * the utilization to reduce possible performance oscillations and
+	 * offset possible performance loss related to moving the workload from
+	 * one CPU to another withing a package/module.
+	 */
+	avg_perf = cpu->sample.core_avg_perf;
+	if (avg_perf > busy_frac)
+		busy_frac += (avg_perf - busy_frac) >> 1;
+
+	sample->busy_scaled = (busy_frac * 100) >> EXT_BITS;
+
+	target = limits->no_turbo || limits->turbo_disabled ?
+			cpu->pstate.max_pstate : cpu->pstate.turbo_pstate;
+	target += target >> 2;
+	return mul_ext_fp(target, busy_frac);
 }
 
 static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
@@ -1317,7 +1333,7 @@ static inline void intel_pstate_adjust_b
 		sample->aperf,
 		sample->tsc,
 		get_avg_frequency(cpu),
-		fp_toint(cpu->iowait_boost * 100));
+		mul_ext_fp(cpu->iowait_boost, 100));
 }
 
 static void intel_pstate_update_util(struct update_util_data *data, u64 time,
@@ -1328,7 +1344,7 @@ static void intel_pstate_update_util(str
 
 	if (pid_params.boost_iowait) {
 		if (flags & SCHED_CPUFREQ_IOWAIT) {
-			cpu->iowait_boost = int_tofp(1);
+			cpu->iowait_boost = int_tofp(1) << EXT_BITS;
 		} else if (cpu->iowait_boost) {
 			/* Clear iowait_boost if the CPU may have been idle. */
 			delta_ns = time - cpu->last_update;

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

* [RFC/RFT][PATCH v2] cpufreq: intel_pstate: Proportional algorithm for Atom
  2016-10-02 17:03 [RFC/RFT][PATCH] cpufreq: intel_pstate: Proportional algorithm for Atom Rafael J. Wysocki
@ 2016-10-05 13:14 ` Rafael J. Wysocki
  2016-10-05 23:58 ` Doug Smythies
  2016-10-06 12:07 ` [RFC/RFT][PATCH v3] " Rafael J. Wysocki
  2 siblings, 0 replies; 5+ messages in thread
From: Rafael J. Wysocki @ 2016-10-05 13:14 UTC (permalink / raw)
  To: Srinivas Pandruvada, Linux PM list
  Cc: Linux Kernel Mailing List, Doug Smythies

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

The PID algorithm used by the intel_pstate driver tends to drive
performance to the minimum for workloads with utilization below the
setpoint, which is undesirable, so replace it with a modified
"proportional" algorithm on Atom.

The new algorithm will set the new P-state to be 1.25 times the
available maximum times the (frequency-invariant) utilization during
the previous sampling period except when the target P-state computed
this way is lower than the average P-state during the previous
sampling period.  In the latter case, it will increase the target by
50% of the difference between it and the average P-state to prevent
performance from dropping down too fast in some cases.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

It is better to compare the average P-state to the target (than to
compare the average perf ratio to the utilization), because that takes
turbo into account more accurately.

Plus if the target is below the min, it is better to compare the min
to the average instead of comparing the target to it.

---
 drivers/cpufreq/intel_pstate.c |   22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -1232,6 +1232,7 @@ static inline int32_t get_target_pstate_
 {
 	struct sample *sample = &cpu->sample;
 	int32_t busy_frac, boost;
+	int target, avg_pstate;
 
 	busy_frac = div_fp(sample->mperf, sample->tsc);
 
@@ -1242,7 +1243,26 @@ static inline int32_t get_target_pstate_
 		busy_frac = boost;
 
 	sample->busy_scaled = busy_frac * 100;
-	return get_avg_pstate(cpu) - pid_calc(&cpu->pid, sample->busy_scaled);
+
+	target = limits->no_turbo || limits->turbo_disabled :
+			cpu->pstate.max_pstate : cpu->pstate.turbo_pstate;
+	target += target >> 2;
+	target = mul_fp(target, busy_frac);
+	if (target < cpu->pstate.min_pstate)
+		target = cpu->pstate.min_pstate;
+
+	/*
+	 * If the average P-state during the previous cycle was higher than the
+	 * current target, add 50% of the difference to the target to reduce
+	 * possible performance oscillations and offset possible performance
+	 * loss related to moving the workload from one CPU to another within
+	 * a package/module.
+	 */
+	avg_pstate = get_avg_pstate(cpu);
+	if (avg_pstate > target)
+		target += (avg_pstate - target) >> 1;
+
+	return target;
 }
 
 static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)

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

* RE: [RFC/RFT][PATCH v2] cpufreq: intel_pstate: Proportional algorithm for Atom
  2016-10-02 17:03 [RFC/RFT][PATCH] cpufreq: intel_pstate: Proportional algorithm for Atom Rafael J. Wysocki
  2016-10-05 13:14 ` [RFC/RFT][PATCH v2] " Rafael J. Wysocki
@ 2016-10-05 23:58 ` Doug Smythies
  2016-10-06 11:57   ` Rafael J. Wysocki
  2016-10-06 12:07 ` [RFC/RFT][PATCH v3] " Rafael J. Wysocki
  2 siblings, 1 reply; 5+ messages in thread
From: Doug Smythies @ 2016-10-05 23:58 UTC (permalink / raw)
  To: 'Rafael J. Wysocki'
  Cc: 'Linux Kernel Mailing List',
	'Srinivas Pandruvada', 'Linux PM list'

Hi Rafael,

It doesn't compile for me. See further down.

On 2016.10.05 06:15 Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> The PID algorithm used by the intel_pstate driver tends to drive
> performance to the minimum for workloads with utilization below the
> setpoint, which is undesirable, so replace it with a modified
> "proportional" algorithm on Atom.
>
> The new algorithm will set the new P-state to be 1.25 times the
> available maximum times the (frequency-invariant) utilization during
> the previous sampling period except when the target P-state computed
> this way is lower than the average P-state during the previous
> sampling period.  In the latter case, it will increase the target by
> 50% of the difference between it and the average P-state to prevent
> performance from dropping down too fast in some cases.
>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>
> It is better to compare the average P-state to the target (than to
> compare the average perf ratio to the utilization), because that takes
> turbo into account more accurately.
>
> Plus if the target is below the min, it is better to compare the min
> to the average instead of comparing the target to it.
>
> ---
> drivers/cpufreq/intel_pstate.c |   22 +++++++++++++++++++++-
> 1 file changed, 21 insertions(+), 1 deletion(-)
>
> Index: linux-pm/drivers/cpufreq/intel_pstate.c
> ===================================================================
> --- linux-pm.orig/drivers/cpufreq/intel_pstate.c
> +++ linux-pm/drivers/cpufreq/intel_pstate.c
> @@ -1232,6 +1232,7 @@ static inline int32_t get_target_pstate_
>  {
> 	struct sample *sample = &cpu->sample;
> 	int32_t busy_frac, boost;
> +	int target, avg_pstate;
> 
> 	busy_frac = div_fp(sample->mperf, sample->tsc);
> 
> @@ -1242,7 +1243,26 @@ static inline int32_t get_target_pstate_
>  		busy_frac = boost;
> 
> 	sample->busy_scaled = busy_frac * 100;
> -	return get_avg_pstate(cpu) - pid_calc(&cpu->pid, sample->busy_scaled);
> +
> +	target = limits->no_turbo || limits->turbo_disabled :
	                                                    ^
	                                                   ^^^
For proper conditional expression syntax, shouldn't that be a "?" ?

I can not get this patch to compile,
but if I change that ":" to a "?" (as in the previous version of this patch)
it compiles.

> +			cpu->pstate.max_pstate : cpu->pstate.turbo_pstate;
> +	target += target >> 2;
> +	target = mul_fp(target, busy_frac);
> +	if (target < cpu->pstate.min_pstate)
> +		target = cpu->pstate.min_pstate;
> +
> +	/*
> +	 * If the average P-state during the previous cycle was higher than the
> +	 * current target, add 50% of the difference to the target to reduce
> +	 * possible performance oscillations and offset possible performance
> +	 * loss related to moving the workload from one CPU to another within
> +	 * a package/module.
> +	 */
> +	avg_pstate = get_avg_pstate(cpu);
> +	if (avg_pstate > target)
> +		target += (avg_pstate - target) >> 1;
> +
> +	return target;
>  }
> 
>  static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
>
> --

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

* Re: [RFC/RFT][PATCH v2] cpufreq: intel_pstate: Proportional algorithm for Atom
  2016-10-05 23:58 ` Doug Smythies
@ 2016-10-06 11:57   ` Rafael J. Wysocki
  0 siblings, 0 replies; 5+ messages in thread
From: Rafael J. Wysocki @ 2016-10-06 11:57 UTC (permalink / raw)
  To: Doug Smythies
  Cc: Rafael J. Wysocki, Linux Kernel Mailing List,
	Srinivas Pandruvada, Linux PM list

On Thu, Oct 6, 2016 at 1:58 AM, Doug Smythies <dsmythies@telus.net> wrote:
> Hi Rafael,
>
> It doesn't compile for me. See further down.
>
> On 2016.10.05 06:15 Rafael J. Wysocki wrote:
>> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>>
>> The PID algorithm used by the intel_pstate driver tends to drive
>> performance to the minimum for workloads with utilization below the
>> setpoint, which is undesirable, so replace it with a modified
>> "proportional" algorithm on Atom.
>>
>> The new algorithm will set the new P-state to be 1.25 times the
>> available maximum times the (frequency-invariant) utilization during
>> the previous sampling period except when the target P-state computed
>> this way is lower than the average P-state during the previous
>> sampling period.  In the latter case, it will increase the target by
>> 50% of the difference between it and the average P-state to prevent
>> performance from dropping down too fast in some cases.
>>
>> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>> ---
>>
>> It is better to compare the average P-state to the target (than to
>> compare the average perf ratio to the utilization), because that takes
>> turbo into account more accurately.
>>
>> Plus if the target is below the min, it is better to compare the min
>> to the average instead of comparing the target to it.
>>
>> ---
>> drivers/cpufreq/intel_pstate.c |   22 +++++++++++++++++++++-
>> 1 file changed, 21 insertions(+), 1 deletion(-)
>>
>> Index: linux-pm/drivers/cpufreq/intel_pstate.c
>> ===================================================================
>> --- linux-pm.orig/drivers/cpufreq/intel_pstate.c
>> +++ linux-pm/drivers/cpufreq/intel_pstate.c
>> @@ -1232,6 +1232,7 @@ static inline int32_t get_target_pstate_
>>  {
>>       struct sample *sample = &cpu->sample;
>>       int32_t busy_frac, boost;
>> +     int target, avg_pstate;
>>
>>       busy_frac = div_fp(sample->mperf, sample->tsc);
>>
>> @@ -1242,7 +1243,26 @@ static inline int32_t get_target_pstate_
>>               busy_frac = boost;
>>
>>       sample->busy_scaled = busy_frac * 100;
>> -     return get_avg_pstate(cpu) - pid_calc(&cpu->pid, sample->busy_scaled);
>> +
>> +     target = limits->no_turbo || limits->turbo_disabled :
>                                                             ^
>                                                            ^^^
> For proper conditional expression syntax, shouldn't that be a "?" ?

Yes, my bad, sorry.

I'll send a v3 shortly.

Thanks,
Rafael

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

* [RFC/RFT][PATCH v3] cpufreq: intel_pstate: Proportional algorithm for Atom
  2016-10-02 17:03 [RFC/RFT][PATCH] cpufreq: intel_pstate: Proportional algorithm for Atom Rafael J. Wysocki
  2016-10-05 13:14 ` [RFC/RFT][PATCH v2] " Rafael J. Wysocki
  2016-10-05 23:58 ` Doug Smythies
@ 2016-10-06 12:07 ` Rafael J. Wysocki
  2 siblings, 0 replies; 5+ messages in thread
From: Rafael J. Wysocki @ 2016-10-06 12:07 UTC (permalink / raw)
  To: Srinivas Pandruvada
  Cc: Linux PM list, Linux Kernel Mailing List, Doug Smythies

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

The PID algorithm used by the intel_pstate driver tends to drive
performance to the minimum for workloads with utilization below the
setpoint, which is undesirable, so replace it with a modified
"proportional" algorithm on Atom.

The new algorithm will set the new P-state to be 1.25 times the
available maximum times the (frequency-invariant) utilization during
the previous sampling period except when the target P-state computed
this way is lower than the average P-state during the previous
sampling period.  In the latter case, it will increase the target by
50% of the difference between it and the average P-state to prevent
performance from dropping down too fast in some cases.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

v1 -> v2:
  It is better to compare the average P-state to the target (than to
  compare the average perf ratio to the utilization), because that takes
  turbo into account more accurately.

  Plus if the target is below the min, it is better to compare the min
  to the average instead of comparing the target to it.

v2 -> v3:
  Fix a typo in the ternary operator reported by Doug.

---
 drivers/cpufreq/intel_pstate.c |   22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

Index: linux-pm/drivers/cpufreq/intel_pstate.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/intel_pstate.c
+++ linux-pm/drivers/cpufreq/intel_pstate.c
@@ -1232,6 +1232,7 @@ static inline int32_t get_target_pstate_
 {
 	struct sample *sample = &cpu->sample;
 	int32_t busy_frac, boost;
+	int target, avg_pstate;
 
 	busy_frac = div_fp(sample->mperf, sample->tsc);
 
@@ -1242,7 +1243,26 @@ static inline int32_t get_target_pstate_
 		busy_frac = boost;
 
 	sample->busy_scaled = busy_frac * 100;
-	return get_avg_pstate(cpu) - pid_calc(&cpu->pid, sample->busy_scaled);
+
+	target = limits->no_turbo || limits->turbo_disabled ?
+			cpu->pstate.max_pstate : cpu->pstate.turbo_pstate;
+	target += target >> 2;
+	target = mul_fp(target, busy_frac);
+	if (target < cpu->pstate.min_pstate)
+		target = cpu->pstate.min_pstate;
+
+	/*
+	 * If the average P-state during the previous cycle was higher than the
+	 * current target, add 50% of the difference to the target to reduce
+	 * possible performance oscillations and offset possible performance
+	 * loss related to moving the workload from one CPU to another within
+	 * a package/module.
+	 */
+	avg_pstate = get_avg_pstate(cpu);
+	if (avg_pstate > target)
+		target += (avg_pstate - target) >> 1;
+
+	return target;
 }
 
 static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)

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

end of thread, other threads:[~2016-10-06 12:01 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-02 17:03 [RFC/RFT][PATCH] cpufreq: intel_pstate: Proportional algorithm for Atom Rafael J. Wysocki
2016-10-05 13:14 ` [RFC/RFT][PATCH v2] " Rafael J. Wysocki
2016-10-05 23:58 ` Doug Smythies
2016-10-06 11:57   ` Rafael J. Wysocki
2016-10-06 12:07 ` [RFC/RFT][PATCH v3] " Rafael J. Wysocki

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