[Mesa-dev] [PATCH 2/2] llvmpipe, draw: improve shader cache debugging

Jose Fonseca jfonseca at vmware.com
Fri Sep 8 14:30:13 UTC 2017


On 08/09/17 02:00, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
> 
> With GALLIVM_DEBUG=perf set, output the relevant stats for shader cache usage
> whenever we have to evict shader variants.
> Also add some output when shaders are deleted (but not with the perf setting
> to keep this one less noisy).
> While here, also don't delete that many shaders when we have to evict. For
> fs, there's potentially some cost if we have to evict due to the required,
> however certainly shader recompiles have a high cost too so I don't think
> evicting one quarter of the cache size makes sense (and, if we're evicting
> based on IR count, we probably typically evict only very few or just one
> shader too). For vs, I'm not sure it even makes sense to evict more than
> one shader at a time, but keep the logic the same for now.
> ---
>   src/gallium/auxiliary/draw/draw_llvm.c             | 10 ++++
>   .../draw/draw_pt_fetch_shade_pipeline_llvm.c       | 55 +++++++++++++---------
>   src/gallium/drivers/llvmpipe/lp_state_fs.c         | 25 ++++++----
>   3 files changed, 59 insertions(+), 31 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
> index 2035720..8de29ea 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm.c
> +++ b/src/gallium/auxiliary/draw/draw_llvm.c
> @@ -2156,6 +2156,11 @@ draw_llvm_destroy_variant(struct draw_llvm_variant *variant)
>   {
>      struct draw_llvm *llvm = variant->llvm;
>   
> +   if (gallivm_debug & (GALLIVM_DEBUG_TGSI | GALLIVM_DEBUG_IR)) {
> +      debug_printf("Deleting VS variant: %u vs variants,\t%u total variants\n",
> +                    variant->shader->variants_cached, llvm->nr_variants);
> +   }
> +
>      gallivm_destroy(variant->gallivm);
>   
>      remove_from_list(&variant->list_item_local);
> @@ -2418,6 +2423,11 @@ draw_gs_llvm_destroy_variant(struct draw_gs_llvm_variant *variant)
>   {
>      struct draw_llvm *llvm = variant->llvm;
>   
> +   if (gallivm_debug & (GALLIVM_DEBUG_TGSI | GALLIVM_DEBUG_IR)) {
> +      debug_printf("Deleting GS variant: %u gs variants,\t%u total variants\n",
> +                    variant->shader->variants_cached, llvm->nr_gs_variants);
> +   }
> +
>      gallivm_destroy(variant->gallivm);
>   
>      remove_from_list(&variant->list_item_local);
> diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
> index 0277cbf..c6492a1 100644
> --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
> +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
> @@ -37,6 +37,7 @@
>   #include "draw/draw_vs.h"
>   #include "draw/draw_llvm.h"
>   #include "gallivm/lp_bld_init.h"
> +#include "gallivm/lp_bld_debug.h"
>   
>   
>   struct llvm_middle_end {
> @@ -71,6 +72,7 @@ static void
>   llvm_middle_end_prepare_gs(struct llvm_middle_end *fpme)
>   {
>      struct draw_context *draw = fpme->draw;
> +   struct draw_llvm *llvm = fpme->llvm;
>      struct draw_geometry_shader *gs = draw->gs.geometry_shader;
>      struct draw_gs_llvm_variant_key *key;
>      struct draw_gs_llvm_variant *variant = NULL;
> @@ -79,7 +81,7 @@ llvm_middle_end_prepare_gs(struct llvm_middle_end *fpme)
>      char store[DRAW_GS_LLVM_MAX_VARIANT_KEY_SIZE];
>      unsigned i;
>   
> -   key = draw_gs_llvm_make_variant_key(fpme->llvm, store);
> +   key = draw_gs_llvm_make_variant_key(llvm, store);
>   
>      /* Search shader's list of variants for the key */
>      li = first_elem(&shader->variants);
> @@ -93,38 +95,42 @@ llvm_middle_end_prepare_gs(struct llvm_middle_end *fpme)
>   
>      if (variant) {
>         /* found the variant, move to head of global list (for LRU) */
> -      move_to_head(&fpme->llvm->gs_variants_list,
> -                   &variant->list_item_global);
> +      move_to_head(&llvm->gs_variants_list, &variant->list_item_global);
>      }
>      else {
>         /* Need to create new variant */
>   
>         /* First check if we've created too many variants.  If so, free
> -       * 25% of the LRU to avoid using too much memory.
> +       * 3.125% of the LRU to avoid using too much memory.
>          */
> -      if (fpme->llvm->nr_gs_variants >= DRAW_MAX_SHADER_VARIANTS) {
> +      if (llvm->nr_gs_variants >= DRAW_MAX_SHADER_VARIANTS) {
> +         if (gallivm_debug & GALLIVM_DEBUG_PERF) {
> +            debug_printf("Evicting GS: %u gs variants,\t%u total variants\n",
> +                      shader->variants_cached, llvm->nr_gs_variants);
> +         }
> +
>            /*
>             * XXX: should we flush here ?
>             */
> -         for (i = 0; i < DRAW_MAX_SHADER_VARIANTS / 4; i++) {
> +         for (i = 0; i < DRAW_MAX_SHADER_VARIANTS / 32; i++) {
>               struct draw_gs_llvm_variant_list_item *item;
> -            if (is_empty_list(&fpme->llvm->gs_variants_list)) {
> +            if (is_empty_list(&llvm->gs_variants_list)) {
>                  break;
>               }
> -            item = last_elem(&fpme->llvm->gs_variants_list);
> +            item = last_elem(&llvm->gs_variants_list);
>               assert(item);
>               assert(item->base);
>               draw_gs_llvm_destroy_variant(item->base);
>            }
>         }
>   
> -      variant = draw_gs_llvm_create_variant(fpme->llvm, gs->info.num_outputs, key);
> +      variant = draw_gs_llvm_create_variant(llvm, gs->info.num_outputs, key);
>   
>         if (variant) {
>            insert_at_head(&shader->variants, &variant->list_item_local);
> -         insert_at_head(&fpme->llvm->gs_variants_list,
> +         insert_at_head(&llvm->gs_variants_list,
>                           &variant->list_item_global);
> -         fpme->llvm->nr_gs_variants++;
> +         llvm->nr_gs_variants++;
>            shader->variants_cached++;
>         }
>      }
> @@ -145,6 +151,7 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
>   {
>      struct llvm_middle_end *fpme = llvm_middle_end(middle);
>      struct draw_context *draw = fpme->draw;
> +   struct draw_llvm *llvm = fpme->llvm;
>      struct draw_vertex_shader *vs = draw->vs.vertex_shader;
>      struct draw_geometry_shader *gs = draw->gs.geometry_shader;
>      const unsigned out_prim = gs ? gs->output_primitive :
> @@ -203,7 +210,7 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
>         char store[DRAW_LLVM_MAX_VARIANT_KEY_SIZE];
>         unsigned i;
>   
> -      key = draw_llvm_make_variant_key(fpme->llvm, store);
> +      key = draw_llvm_make_variant_key(llvm, store);
>   
>         /* Search shader's list of variants for the key */
>         li = first_elem(&shader->variants);
> @@ -217,38 +224,42 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
>   
>         if (variant) {
>            /* found the variant, move to head of global list (for LRU) */
> -         move_to_head(&fpme->llvm->vs_variants_list,
> -                      &variant->list_item_global);
> +         move_to_head(&llvm->vs_variants_list, &variant->list_item_global);
>         }
>         else {
>            /* Need to create new variant */
>   
>            /* First check if we've created too many variants.  If so, free
> -          * 25% of the LRU to avoid using too much memory.
> +          * 3.125% of the LRU to avoid using too much memory.
>             */
> -         if (fpme->llvm->nr_variants >= DRAW_MAX_SHADER_VARIANTS) {
> +         if (llvm->nr_variants >= DRAW_MAX_SHADER_VARIANTS) {
> +            if (gallivm_debug & GALLIVM_DEBUG_PERF) {
> +               debug_printf("Evicting VS: %u vs variants,\t%u total variants\n",
> +                         shader->variants_cached, llvm->nr_variants);
> +            }
> +
>               /*
>                * XXX: should we flush here ?
>                */
> -            for (i = 0; i < DRAW_MAX_SHADER_VARIANTS / 4; i++) {
> +            for (i = 0; i < DRAW_MAX_SHADER_VARIANTS / 32; i++) {
>                  struct draw_llvm_variant_list_item *item;
> -               if (is_empty_list(&fpme->llvm->vs_variants_list)) {
> +               if (is_empty_list(&llvm->vs_variants_list)) {
>                     break;
>                  }
> -               item = last_elem(&fpme->llvm->vs_variants_list);
> +               item = last_elem(&llvm->vs_variants_list);
>                  assert(item);
>                  assert(item->base);
>                  draw_llvm_destroy_variant(item->base);
>               }
>            }
>   
> -         variant = draw_llvm_create_variant(fpme->llvm, nr, key);
> +         variant = draw_llvm_create_variant(llvm, nr, key);
>   
>            if (variant) {
>               insert_at_head(&shader->variants, &variant->list_item_local);
> -            insert_at_head(&fpme->llvm->vs_variants_list,
> +            insert_at_head(&llvm->vs_variants_list,
>                              &variant->list_item_global);
> -            fpme->llvm->nr_variants++;
> +            llvm->nr_variants++;
>               shader->variants_cached++;
>            }
>         }
> diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
> index df3557a..9a43f01 100644
> --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
> +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
> @@ -2993,14 +2993,13 @@ void
>   llvmpipe_remove_shader_variant(struct llvmpipe_context *lp,
>                                  struct lp_fragment_shader_variant *variant)
>   {
> -   if (gallivm_debug & GALLIVM_DEBUG_IR) {
> -      debug_printf("llvmpipe: del fs #%u var #%u v created #%u v cached"
> -                   " #%u v total cached #%u\n",
> -                   variant->shader->no,
> -                   variant->no,
> +   if ((LP_DEBUG & DEBUG_FS) || (gallivm_debug & GALLIVM_DEBUG_IR)) {
> +      debug_printf("llvmpipe: del fs #%u var %u v created %u v cached %u "
> +                   "v total cached %u inst %u total inst %u\n",
> +                   variant->shader->no, variant->no,
>                      variant->shader->variants_created,
>                      variant->shader->variants_cached,
> -                   lp->nr_fs_variants);
> +                   lp->nr_fs_variants, variant->nr_instrs, lp->nr_fs_instrs);
>      }
>   
>      gallivm_destroy(variant->gallivm);
> @@ -3357,7 +3356,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
>         unsigned i;
>         unsigned variants_to_cull;
>   
> -      if (0) {
> +      if (LP_DEBUG & DEBUG_FS) {
>            debug_printf("%u variants,\t%u instrs,\t%u instrs/variant\n",
>                         lp->nr_fs_variants,
>                         lp->nr_fs_instrs,
> @@ -3365,14 +3364,22 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
>         }
>   
>         /* First, check if we've exceeded the max number of shader variants.
> -       * If so, free 25% of them (the least recently used ones).
> +       * If so, free 6.25% of them (the least recently used ones).
>          */
> -      variants_to_cull = lp->nr_fs_variants >= LP_MAX_SHADER_VARIANTS ? LP_MAX_SHADER_VARIANTS / 4 : 0;
> +      variants_to_cull = lp->nr_fs_variants >= LP_MAX_SHADER_VARIANTS ? LP_MAX_SHADER_VARIANTS / 16 : 0;
>   
>         if (variants_to_cull ||
>             lp->nr_fs_instrs >= LP_MAX_SHADER_INSTRUCTIONS) {
>            struct pipe_context *pipe = &lp->pipe;
>   
> +         if (gallivm_debug & GALLIVM_DEBUG_PERF) {
> +            debug_printf("Evicting FS: %u fs variants,\t%u total variants,"
> +                         "\t%u instrs,\t%u instrs/variant\n",
> +                         shader->variants_cached,
> +                         lp->nr_fs_variants, lp->nr_fs_instrs,
> +                         lp->nr_fs_instrs / lp->nr_fs_variants);
> +         }
> +
>            /*
>             * XXX: we need to flush the context until we have some sort of
>             * reference counting in fragment shaders as they may still be binned
> 

Series is

Reviewed-by: Jose Fonseca <jfonseca at vmware.com>


More information about the mesa-dev mailing list