[Mesa-dev] [PATCH v2 09/42] i965: Implement selection of the closest L3 configuration based on a vector of weights.

Samuel Iglesias Gonsálvez siglesias at igalia.com
Wed Nov 25 06:33:40 PST 2015


Reviewed-by: Samuel Iglesias Gonsálvez <siglesias at igalia.com>

On 18/11/15 06:54, Jordan Justen wrote:
> From: Francisco Jerez <currojerez at riseup.net>
> 
> The input of the L3 set-up code is a vector giving the approximate
> desired relative size of each partition.  This implements logic to
> compare the input vector against the table of validated configurations
> for the device and pick the closest compatible one.
> ---
>  src/mesa/drivers/dri/i965/gen7_l3_state.c | 95 +++++++++++++++++++++++++++++++
>  1 file changed, 95 insertions(+)
> 
> diff --git a/src/mesa/drivers/dri/i965/gen7_l3_state.c b/src/mesa/drivers/dri/i965/gen7_l3_state.c
> index c863b7f..4d0cfcd 100644
> --- a/src/mesa/drivers/dri/i965/gen7_l3_state.c
> +++ b/src/mesa/drivers/dri/i965/gen7_l3_state.c
> @@ -163,6 +163,101 @@ get_l3_way_size(const struct brw_device_info *devinfo)
>  }
>  
>  /**
> + * L3 configuration represented as a vector of weights giving the desired
> + * relative size of each partition.  The scale is arbitrary, only the ratios
> + * between weights will have an influence on the selection of the closest L3
> + * configuration.
> + */
> +struct brw_l3_weights {
> +   float w[NUM_L3P];
> +};
> +
> +/**
> + * L1-normalize a vector of L3 partition weights.
> + */
> +static struct brw_l3_weights
> +norm_l3_weights(struct brw_l3_weights w)
> +{
> +   float sz = 0;
> +
> +   for (unsigned i = 0; i < NUM_L3P; i++)
> +      sz += w.w[i];
> +
> +   for (unsigned i = 0; i < NUM_L3P; i++)
> +      w.w[i] /= sz;
> +
> +   return w;
> +}
> +
> +/**
> + * Get the relative partition weights of the specified L3 configuration.
> + */
> +static struct brw_l3_weights
> +get_config_l3_weights(const struct brw_l3_config *cfg)
> +{
> +   if (cfg) {
> +      struct brw_l3_weights w;
> +
> +      for (unsigned i = 0; i < NUM_L3P; i++)
> +         w.w[i] = cfg->n[i];
> +
> +      return norm_l3_weights(w);
> +   } else {
> +      const struct brw_l3_weights w = { { 0 } };
> +      return w;
> +   }
> +}
> +
> +/**
> + * Distance between two L3 configurations represented as vectors of weights.
> + * Usually just the L1 metric except when the two configurations are
> + * considered incompatible in which case the distance will be infinite.  Note
> + * that the compatibility condition is asymmetric -- They will be considered
> + * incompatible whenever the reference configuration \p w0 requires SLM, DC,
> + * or URB but \p w1 doesn't provide it.
> + */
> +static float
> +diff_l3_weights(struct brw_l3_weights w0, struct brw_l3_weights w1)
> +{
> +   if ((w0.w[L3P_SLM] && !w1.w[L3P_SLM]) ||
> +       (w0.w[L3P_DC] && !w1.w[L3P_DC] && !w1.w[L3P_ALL]) ||
> +       (w0.w[L3P_URB] && !w1.w[L3P_URB])) {
> +      return HUGE_VALF;
> +
> +   } else {
> +      float dw = 0;
> +
> +      for (unsigned i = 0; i < NUM_L3P; i++)
> +         dw += fabs(w0.w[i] - w1.w[i]);
> +
> +      return dw;
> +   }
> +}
> +
> +/**
> + * Return the closest validated L3 configuration for the specified device and
> + * weight vector.
> + */
> +static const struct brw_l3_config *
> +get_l3_config(const struct brw_device_info *devinfo, struct brw_l3_weights w0)
> +{
> +   const struct brw_l3_config *const cfgs = get_l3_configs(devinfo);
> +   const struct brw_l3_config *cfg_best = NULL;
> +   float dw_best = HUGE_VALF;
> +
> +   for (const struct brw_l3_config *cfg = cfgs; cfg->n[L3P_URB]; cfg++) {
> +      const float dw = diff_l3_weights(w0, get_config_l3_weights(cfg));
> +
> +      if (dw < dw_best) {
> +         cfg_best = cfg;
> +         dw_best = dw;
> +      }
> +   }
> +
> +   return cfg_best;
> +}
> +
> +/**
>   * Program the hardware to use the specified L3 configuration.
>   */
>  static void
> 


More information about the mesa-dev mailing list