[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