[Mesa-dev] [PATCH] i965/fs: Make the first pre-allocation heuristic be the post heuristic.
Jordan Justen
jljusten at gmail.com
Wed Nov 20 00:49:08 PST 2013
Making madness (e9daead7) legit? :)
Reviewed-by: Jordan Justen <jordan.l.justen at intel.com>
On Tue, Nov 19, 2013 at 11:34 PM, Eric Anholt <eric at anholt.net> wrote:
> I recently made us try two different things that tried to reduce register
> pressure so that we would be more likely to allocate successfully. But
> now that we have the logic for trying two, we can make the first thing we
> try be the normal, not-prioritizing-register-pressure heuristic.
>
> This means one less scheduling pass in the common case of that heuristic
> not producing spills, plus the best schedule we know how to produce, if
> that one happens to succeed. This is important, because our register
> allocation produces a lot of possibly avoidable dependencies for the
> post-register-allocation schedule, despite ra_set_allocate_round_robin().
>
> GLB2.7: 1.04127% +/- 0.732461% fps improvement (n=31)
> nexuiz: No difference (n=5)
> lightsmark: 0.838512% +/- 0.300147% fps improvement (n=86)
> minecraft apitrace: No difference (n=15)
> ---
> src/mesa/drivers/dri/i965/brw_fs.cpp | 62 ++++++++++++++--------
> .../drivers/dri/i965/brw_schedule_instructions.cpp | 4 +-
> src/mesa/drivers/dri/i965/brw_shader.h | 1 +
> 3 files changed, 44 insertions(+), 23 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
> index 8b3f8df..dbe7503 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
> @@ -3190,6 +3190,7 @@ fs_visitor::run()
> {
> sanity_param_count = fp->Base.Parameters->NumParameters;
> uint32_t orig_nr_params = c->prog_data.nr_params;
> + bool allocated_without_spills;
>
> assign_binding_table_offsets();
>
> @@ -3273,27 +3274,45 @@ fs_visitor::run()
> assign_curb_setup();
> assign_urb_setup();
>
> - schedule_instructions(SCHEDULE_PRE_NON_LIFO);
> + static enum instruction_scheduler_mode pre_modes[] = {
> + SCHEDULE_PRE,
> + SCHEDULE_PRE_NON_LIFO,
> + SCHEDULE_PRE_LIFO,
> + };
>
> - if (0)
> - assign_regs_trivial();
> - else {
> - if (!assign_regs(false)) {
> - /* Try a non-spilling register allocation again with a different
> - * scheduling heuristic.
> - */
> - schedule_instructions(SCHEDULE_PRE_LIFO);
> - if (!assign_regs(false)) {
> - if (dispatch_width == 16) {
> - fail("Failure to register allocate. Reduce number of "
> - "live scalar values to avoid this.");
> - } else {
> - while (!assign_regs(true)) {
> - if (failed)
> - break;
> - }
> - }
> - }
> + /* Try each scheduling heuristic to see if it can successfully register
> + * allocate without spilling. They should be ordered by decreasing
> + * performance but increasing likelihood of allocating.
> + */
> + for (unsigned i = 0; i < ARRAY_SIZE(pre_modes); i++) {
> + schedule_instructions(pre_modes[i]);
> +
> + if (0) {
> + assign_regs_trivial();
> + allocated_without_spills = true;
> + } else {
> + allocated_without_spills = assign_regs(false);
> + }
> + if (allocated_without_spills)
> + break;
> + }
> +
> + if (!allocated_without_spills) {
> + /* We assume that any spilling is worse than just dropping back to
> + * SIMD8. There's probably actually some intermediate point where
> + * SIMD16 with a couple of spills is still better.
> + */
> + if (dispatch_width == 16) {
> + fail("Failure to register allocate. Reduce number of "
> + "live scalar values to avoid this.");
> + }
> +
> + /* Since we're out of heuristics, just go spill registers until we
> + * get an allocation.
> + */
> + while (!assign_regs(true)) {
> + if (failed)
> + break;
> }
> }
> }
> @@ -3308,7 +3327,8 @@ fs_visitor::run()
> if (failed)
> return false;
>
> - schedule_instructions(SCHEDULE_POST);
> + if (!allocated_without_spills)
> + schedule_instructions(SCHEDULE_POST);
>
> if (dispatch_width == 8) {
> c->prog_data.reg_blocks = brw_register_blocks(grf_used);
> diff --git a/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp b/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp
> index a4fae0d..a40a46a 100644
> --- a/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp
> @@ -1140,10 +1140,10 @@ fs_instruction_scheduler::choose_instruction_to_schedule()
> {
> schedule_node *chosen = NULL;
>
> - if (post_reg_alloc) {
> + if (mode == SCHEDULE_PRE || mode == SCHEDULE_POST) {
> int chosen_time = 0;
>
> - /* Of the instructions closest ready to execute or the closest to
> + /* Of the instructions ready to execute or the closest to
> * being ready, choose the oldest one.
> */
> foreach_list(node, &instructions) {
> diff --git a/src/mesa/drivers/dri/i965/brw_shader.h b/src/mesa/drivers/dri/i965/brw_shader.h
> index aba24c5..34779ff 100644
> --- a/src/mesa/drivers/dri/i965/brw_shader.h
> +++ b/src/mesa/drivers/dri/i965/brw_shader.h
> @@ -60,6 +60,7 @@ public:
> };
>
> enum instruction_scheduler_mode {
> + SCHEDULE_PRE,
> SCHEDULE_PRE_NON_LIFO,
> SCHEDULE_PRE_LIFO,
> SCHEDULE_POST,
> --
> 1.8.4.rc3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list