Beispiel #1
0
int main() {
    unsigned long delay_tlbmiss;
    unsigned long long cpms;

    cpms = cycles_per_ms();

    printf("%-20s %6s %8s %10s %12s %24s\n",
           "Test Name",
           "Stride",
           "NumOps",
           "Iterations",
           "Time/ms",
           "Cycles/Iteration");

    printf("%-20s %6s %8s %10s %12s %24s\n",
           "---------",
           "------",
           "------",
           "----------",
           "-------",
           "----------------");

    delay_tlbmiss = measure_latency(cpms);
    printf("Report\n------\n");
    printf("Delay from TLB Miss: %lu clockcycles\n", delay_tlbmiss);

    exit(0);

}
Beispiel #2
0
int main(){
	const int nrows = 12;
	int nlist[nrows] = {1, 2, 4, 
		       8, 16, 24, 
		       32, 40, 60, 
		       1000, 10*1000, 100*1000};
	const char *rows[nrows] =  {"1", "2", "4", 
				    "8", "16", "24", 
				    "32", "40", "60", 
				    "1000", "10*1000", "100*1000"};
	const int ncols = 3;
	const char *cols[ncols] = {"min", "median", "max"};
	
	double cyc2dram[nrows*ncols];
	StatVector stats(NTRIALS);
	
	for(int i=0; i < nrows; i++){
		measure_latency(nlist[i], stats);
		cyc2dram[i+0*nrows] = stats.min();
		cyc2dram[i+1*nrows] = stats.median();
		cyc2dram[i+2*nrows] = stats.max();
	}
	
	verify_dir("DBG");
#ifdef MEMWALK
	const char* fname = "DBG/latency_memwalk.txt";
#else
	const char* fname = "DBG/latency_clflush.txt";
#endif
	link_cout(fname);

	Table tbl;
	tbl.dim(nrows, ncols);
	tbl.rows(rows);
	tbl.cols(cols);
	tbl.data(cyc2dram);
	char banner[200];
	sprintf(banner, "cycles to dram, ntrials = %d, when N pages accessed",
		NTRIALS);
	tbl.print(banner);
	
	unlink_cout();
}
Beispiel #3
0
// Runs a latency test and reports the results as JSON written to the given
// connection.
static void report_latency(struct mg_connection *connection,
    const uint8_t magic_pattern[]) {
  double key_down_latency_ms = 0;
  double scroll_latency_ms = 0;
  double max_js_pause_time_ms = 0;
  double max_css_pause_time_ms = 0;
  double max_scroll_pause_time_ms = 0;
  char *error = "Unknown error.";
  if (!measure_latency(magic_pattern,
                       &key_down_latency_ms,
                       &scroll_latency_ms,
                       &max_js_pause_time_ms,
                       &max_css_pause_time_ms,
                       &max_scroll_pause_time_ms,
                       &error)) {
    // Report generic error.
    debug_log("measure_latency reported error: %s", error);
    mg_printf(connection, "HTTP/1.1 500 Internal Server Error\r\n"
              "Access-Control-Allow-Origin: *\r\n"
              "Content-Type: text/plain\r\n\r\n"
              "%s", error);
  } else {
    // Send the measured latency information back as JSON.
    mg_printf(connection, "HTTP/1.1 200 OK\r\n"
              "Access-Control-Allow-Origin: *\r\n"
              "Cache-Control: no-cache\r\n"
              "Content-Type: text/plain\r\n\r\n"
              "{ \"keyDownLatencyMs\": %f, "
              "\"scrollLatencyMs\": %f, "
              "\"maxJSPauseTimeMs\": %f, "
              "\"maxCssPauseTimeMs\": %f, "
              "\"maxScrollPauseTimeMs\": %f}",
              key_down_latency_ms,
              scroll_latency_ms,
              max_js_pause_time_ms,
              max_css_pause_time_ms,
              max_scroll_pause_time_ms);
  }
}
// Main test function. Locates the given magic pixel pattern on the screen, then
// runs one full latency test, sending input events and recording responses. On
// success, the results of the test are reported in the output parameters, and
// true is returned. If the test fails, the error parameter is filled in with
// an error message and false is returned.
bool measure_latency(
    const uint8_t magic_pattern[],
    double *out_key_down_latency_ms,
    double *out_scroll_latency_ms,
    double *out_max_js_pause_time_ms,
    double *out_max_css_pause_time_ms,
    double *out_max_scroll_pause_time_ms,
    char **error) {
  screenshot *screenshot = take_screenshot(0, 0, UINT32_MAX, UINT32_MAX);
  if (!screenshot) {
    *error = "Failed to take screenshot.";
    return false;
  }
  assert(screenshot->width > 0 && screenshot->height > 0);

  size_t x, y;
  bool found_pattern = find_pattern(magic_pattern, screenshot, &x, &y);
  free_screenshot(screenshot);
  if (!found_pattern) {
    *error = "Failed to find test pattern on screen.";
    return false;
  }
  uint8_t full_pattern[pattern_bytes];
  for (int i = 0; i < pattern_magic_bytes; i++) {
    full_pattern[i] = magic_pattern[i];
  }
  measurement_t measurement;
  measurement_t previous_measurement;
  memset(&measurement, 0, sizeof(measurement_t));
  memset(&previous_measurement, 0, sizeof(measurement_t));
  int screenshots = 0;
  bool first_screenshot_successful = read_data_from_screen((uint32_t)x,
      (uint32_t) y, magic_pattern, &measurement);
  if (!first_screenshot_successful) {
    *error = "Failed to read data from test pattern.";
    return false;
  }
  if (measurement.test_mode == TEST_MODE_NATIVE_REFERENCE) {
    uint8_t *test_pattern = (uint8_t *)malloc(pattern_bytes);
    memset(test_pattern, 0, pattern_bytes);
    for (int i = 0; i < pattern_magic_bytes; i++) {
      test_pattern[i] = rand();
    }
    if (!open_native_reference_window(test_pattern)) {
      *error = "Failed to open native reference window.";
      return false;
    }
    bool return_value = measure_latency(test_pattern, out_key_down_latency_ms, out_scroll_latency_ms, out_max_js_pause_time_ms, out_max_css_pause_time_ms, out_max_scroll_pause_time_ms, error);
    if (!close_native_reference_window()) {
      debug_log("Failed to close native reference window.");
    };
    return return_value;
  }
  int64_t start_time = measurement.screenshot_time;
  previous_measurement = measurement;
  statistic javascript_frames;
  statistic css_frames;
  statistic key_down_events;
  statistic scroll_stats;
  init_statistic("javascript_frames", &javascript_frames,
      measurement.javascript_frames, start_time);
  init_statistic("key_down_events", &key_down_events,
      measurement.key_down_events, start_time);
  init_statistic("css_frames", &css_frames, measurement.css_frames, start_time);
  init_statistic("scroll", &scroll_stats, measurement.scroll_position,
      start_time);
  int sent_events = 0;
  int scroll_x = x + 40;
  int scroll_y = y + 40;
  int64_t last_scroll_sent = start_time;
  if (measurement.test_mode == TEST_MODE_SCROLL_LATENCY) {
    send_scroll_down(scroll_x, scroll_y);
    scroll_stats.previous_change_time = get_nanoseconds();
  }
  while(true) {
    bool screenshot_successful = read_data_from_screen((uint32_t)x,
        (uint32_t) y, magic_pattern, &measurement);
    if (!screenshot_successful) {
      *error = "Test window moved during test. The test window must remain "
          "stationary and focused during the entire test.";
      return false;
    }
    if (measurement.test_mode == TEST_MODE_ABORT) {
      *error = "Test aborted.";
      return false;
    }
    screenshots++;
    int64_t screenshot_time = measurement.screenshot_time;
    int64_t previous_screenshot_time = previous_measurement.screenshot_time;
    debug_log("screenshot time %f",
        (screenshot_time - previous_screenshot_time) /
            (double)nanoseconds_per_millisecond);
    update_statistic(&javascript_frames, measurement.javascript_frames,
        screenshot_time, previous_screenshot_time);
    update_statistic(&key_down_events, measurement.key_down_events,
        screenshot_time, previous_screenshot_time);
    update_statistic(&css_frames, measurement.css_frames, screenshot_time,
        previous_screenshot_time);
    bool scroll_updated = update_statistic(&scroll_stats,
        measurement.scroll_position, screenshot_time, previous_screenshot_time);

    if (measurement.test_mode == TEST_MODE_JAVASCRIPT_LATENCY) {
      if (key_down_events.measurements >= latency_measurements_to_take) {
        break;
      }
      if (key_down_events.value_delta > sent_events) {
        *error = "More events received than sent! This is probably a bug in "
            "the test.";
        return false;
      }
      if (screenshot_time - key_down_events.previous_change_time >
          event_response_timeout_ms * nanoseconds_per_millisecond) {
        *error = "Browser did not respond to keyboard input. Make sure the "
            "test page remains focused for the entire test.";
        return false;
      }
      if (key_down_events.value_delta == sent_events) {
        // We want to avoid sending input events at a predictable time relative
        // to frames, so introduce a random delay of up to 1 frame (16.67 ms)
        // before sending the next event.
        usleep((rand() % 17) * 1000);
        if (!send_keystroke_z()) {
          *error = "Failed to send keystroke for \"Z\" key to test window.";
          return false;
        }
        key_down_events.previous_change_time = get_nanoseconds();
        sent_events++;
      }
    } else if (measurement.test_mode == TEST_MODE_SCROLL_LATENCY) {
        if (scroll_stats.measurements >= latency_measurements_to_take) {
          break;
        }
        if (screenshot_time - scroll_stats.previous_change_time >
            event_response_timeout_ms * nanoseconds_per_millisecond) {
          *error = "Browser did not respond to scroll events. Make sure the "
              "test page remains focused for the entire test.";
          return false;
        }
        if (scroll_updated) {
          // We saw the start of a scroll. Wait for the scroll animation to
          // finish before continuing. We assume the animation is finished if
          // it's been 100 milliseconds since we last saw the scroll position
          // change.
          int64_t scroll_update_time = screenshot_time;
          int64_t scroll_wait_start_time = screenshot_time;
          while (screenshot_time - scroll_update_time <
                 100 * nanoseconds_per_millisecond) {
            screenshot_successful = read_data_from_screen((uint32_t)x,
                (uint32_t) y, magic_pattern, &measurement);
            if (!screenshot_successful) {
              *error = "Test window moved during test. The test window must "
                  "remain stationary and focused during the entire test.";
              return false;
            }
            screenshot_time = measurement.screenshot_time;
            if (screenshot_time - scroll_wait_start_time >
                nanoseconds_per_second) {
              *error = "Browser kept scrolling for more than 1 second after a "
                  "single scrollwheel event.";
              return false;
            }
            if (measurement.scroll_position != scroll_stats.value) {
              scroll_stats.value = measurement.scroll_position;
              scroll_update_time = screenshot_time;
            }
          }
          // We want to avoid sending input events at a predictable time
          // relative to frames, so introduce a random delay of up to 1 frame
          // (16.67 ms) before sending the next event.
          usleep((rand() % 17) * 1000);
          send_scroll_down(scroll_x, scroll_y);
          scroll_stats.previous_change_time = get_nanoseconds();
        }
    } else if (measurement.test_mode == TEST_MODE_PAUSE_TIME) {
      // For the pause time test we want the browser to scroll continuously.
      // Send a scroll event every frame.
      if (screenshot_time - last_scroll_sent >
          17 * nanoseconds_per_millisecond) {
        send_scroll_down(scroll_x, scroll_y);
        last_scroll_sent = get_nanoseconds();
      }
    } else if (measurement.test_mode == TEST_MODE_PAUSE_TIME_TEST_FINISHED) {
      break;
    } else {
      *error = "Invalid test type. This is a bug in the test.";
      return false;
    }

    if (screenshot_time - start_time >
        test_timeout_ms * nanoseconds_per_millisecond) {
      *error = "Timeout.";
      return false;
    }
    previous_measurement = measurement;
    usleep(0);
  }
  // The latency we report is the midpoint of the interval given by the average
  // upper and lower bounds we've computed.
  *out_key_down_latency_ms =
      (upper_bound_ms(&key_down_events) + lower_bound_ms(&key_down_events)) / 2;
  *out_scroll_latency_ms =
      (upper_bound_ms(&scroll_stats) + lower_bound_ms(&scroll_stats) / 2);
  *out_max_js_pause_time_ms =
      javascript_frames.max_lower_bound / (double) nanoseconds_per_millisecond;
  *out_max_css_pause_time_ms =
      css_frames.max_lower_bound / (double) nanoseconds_per_millisecond;
  *out_max_scroll_pause_time_ms =
      scroll_stats.max_lower_bound / (double) nanoseconds_per_millisecond;
  debug_log("out_key_down_latency_ms: %f out_scroll_latency_ms: %f "
      "out_max_js_pause_time_ms: %f out_max_css_pause_time: %f\n "
      "out_max_scroll_pause_time_ms: %f",
      *out_key_down_latency_ms,
      *out_scroll_latency_ms,
      *out_max_js_pause_time_ms,
      *out_max_css_pause_time_ms,
      *out_max_scroll_pause_time_ms);
  return true;
}