i965: Scale shader_time to compensate for resets.
authorEric Anholt <eric@anholt.net>
Mon, 10 Dec 2012 17:44:19 +0000 (09:44 -0800)
committerEric Anholt <eric@anholt.net>
Fri, 14 Dec 2012 23:05:10 +0000 (15:05 -0800)
Some shaders experience resets more than others, which skews the numbers
reported.  Attempt to correct for this by linearly scaling according to
the number of resets that happen.

Note that will not be accurate if invocations of shaders have varying
times and longer invocations are more likely to reset.  However, this
should at least be better than the previous situation.

src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_program.c
src/mesa/drivers/dri/i965/brw_vec4.cpp

index dc25cabcf5308f0428ee7600683b4a8d75a1039a..eba9eb590168b81660d93f0ce1005cccdd2faade 100644 (file)
@@ -655,8 +655,14 @@ struct brw_tracked_state {
 enum shader_time_shader_type {
    ST_NONE,
    ST_VS,
+   ST_VS_WRITTEN,
+   ST_VS_RESET,
    ST_FS8,
+   ST_FS8_WRITTEN,
+   ST_FS8_RESET,
    ST_FS16,
+   ST_FS16_WRITTEN,
+   ST_FS16_RESET,
 };
 
 /* Flags for brw->state.cache.
index 2f4c6691ee8422defbe21cc3c191a88a81a38b9c..f428a83d212872076dbeefd7eaeddc932e896a77 100644 (file)
@@ -505,12 +505,16 @@ fs_visitor::emit_shader_time_end()
 {
    current_annotation = "shader time end";
 
-   enum shader_time_shader_type type;
+   enum shader_time_shader_type type, written_type, reset_type;
    if (dispatch_width == 8) {
       type = ST_FS8;
+      written_type = ST_FS8_WRITTEN;
+      reset_type = ST_FS8_RESET;
    } else {
       assert(dispatch_width == 16);
       type = ST_FS16;
+      written_type = ST_FS16_WRITTEN;
+      reset_type = ST_FS16_RESET;
    }
 
    fs_reg shader_end_time = get_timestamp();
@@ -537,7 +541,9 @@ fs_visitor::emit_shader_time_end()
    emit(ADD(diff, diff, fs_reg(-2u)));
 
    emit_shader_time_write(type, diff);
-
+   emit_shader_time_write(written_type, fs_reg(1u));
+   emit(BRW_OPCODE_ELSE);
+   emit_shader_time_write(reset_type, fs_reg(1u));
    emit(BRW_OPCODE_ENDIF);
 
    pop_force_uncompressed();
index 1859041bc279034e3abb693a58b90c91f966fc46..035824171e3b0aa54c4da24bbd9229892dce1c4e 100644 (file)
@@ -221,17 +221,74 @@ compare_time(const void *a, const void *b)
       return 1;
 }
 
+static void
+get_written_and_reset(struct brw_context *brw, int i,
+                      uint64_t *written, uint64_t *reset)
+{
+   enum shader_time_shader_type type = brw->shader_time.types[i];
+   assert(type == ST_VS || type == ST_FS8 || type == ST_FS16);
+
+   /* Find where we recorded written and reset. */
+   int wi, ri;
+
+   for (wi = i; brw->shader_time.types[wi] != type + 1; wi++)
+      ;
+
+   for (ri = i; brw->shader_time.types[ri] != type + 2; ri++)
+      ;
+
+   *written = brw->shader_time.cumulative[wi];
+   *reset = brw->shader_time.cumulative[ri];
+}
+
 static void
 brw_report_shader_time(struct brw_context *brw)
 {
    if (!brw->shader_time.bo || !brw->shader_time.num_entries)
       return;
 
+   uint64_t scaled[brw->shader_time.num_entries];
    uint64_t *sorted[brw->shader_time.num_entries];
    double total = 0;
    for (int i = 0; i < brw->shader_time.num_entries; i++) {
-      sorted[i] = &brw->shader_time.cumulative[i];
-      total += brw->shader_time.cumulative[i];
+      uint64_t written = 0, reset = 0;
+
+      sorted[i] = &scaled[i];
+
+      switch (brw->shader_time.types[i]) {
+      case ST_VS_WRITTEN:
+      case ST_VS_RESET:
+      case ST_FS8_WRITTEN:
+      case ST_FS8_RESET:
+      case ST_FS16_WRITTEN:
+      case ST_FS16_RESET:
+         /* We'll handle these when along with the time. */
+         scaled[i] = 0;
+         continue;
+
+      case ST_VS:
+      case ST_FS8:
+      case ST_FS16:
+         get_written_and_reset(brw, i, &written, &reset);
+         break;
+
+      default:
+         /* I sometimes want to print things that aren't the 3 shader times.
+          * Just print the sum in that case.
+          */
+         written = 1;
+         reset = 0;
+         break;
+      }
+
+      uint64_t time = brw->shader_time.cumulative[i];
+      if (written) {
+         scaled[i] = time / written * (written + reset);
+      } else {
+         scaled[i] = time;
+      }
+
+      total += scaled[i];
    }
 
    if (total == 0) {
@@ -245,7 +302,10 @@ brw_report_shader_time(struct brw_context *brw)
    printf("type   ID      cycles spent                   %% of total\n");
    for (int s = 0; s < brw->shader_time.num_entries; s++) {
       /* Work back from the sorted pointers times to a time to print. */
-      int i = sorted[s] - brw->shader_time.cumulative;
+      int i = sorted[s] - scaled;
+
+      if (scaled[i] == 0)
+         continue;
 
       int shader_num = -1;
       if (brw->shader_time.programs[i]) {
@@ -268,9 +328,9 @@ brw_report_shader_time(struct brw_context *brw)
       }
 
       printf("%16lld (%7.2f Gcycles)      %4.1f%%\n",
-             (long long)brw->shader_time.cumulative[i],
-             (double)brw->shader_time.cumulative[i] / 1000000000.0,
-             (double)brw->shader_time.cumulative[i] / total * 100.0);
+             (long long)scaled[i],
+             (double)scaled[i] / 1000000000.0,
+             (double)scaled[i] / total * 100.0);
    }
 }
 
index 28199dde80e2159c70b09c6c8f8d974bc9c3afe3..436ba97e1473608ab24fd86c7b5eef2e07a42a69 100644 (file)
@@ -1104,7 +1104,9 @@ vec4_visitor::emit_shader_time_end()
    emit(ADD(diff, src_reg(diff), src_reg(-2u)));
 
    emit_shader_time_write(ST_VS, src_reg(diff));
-
+   emit_shader_time_write(ST_VS_WRITTEN, src_reg(1u));
+   emit(BRW_OPCODE_ELSE);
+   emit_shader_time_write(ST_VS_RESET, src_reg(1u));
    emit(BRW_OPCODE_ENDIF);
 }