int main(int argc, char **argv) { int fd = drm_open_driver(DRIVER_INTEL); enum map {CPU, GTT, WC} map = CPU; enum dir {READ, WRITE, CLEAR, FAULT} dir = READ; int tiling = I915_TILING_NONE; void *buf = malloc(OBJECT_SIZE); uint32_t handle; void *ptr, *src, *dst; int reps = 13; int c, size; while ((c = getopt (argc, argv, "m:d:r:t:")) != -1) { switch (c) { case 'm': if (strcmp(optarg, "cpu") == 0) map = CPU; else if (strcmp(optarg, "gtt") == 0) map = GTT; else if (strcmp(optarg, "wc") == 0) map = WC; else abort(); break; case 'd': if (strcmp(optarg, "read") == 0) dir = READ; else if (strcmp(optarg, "write") == 0) dir = WRITE; else if (strcmp(optarg, "clear") == 0) dir = CLEAR; else if (strcmp(optarg, "fault") == 0) dir = FAULT; else abort(); break; case 't': if (strcmp(optarg, "x") == 0) tiling = I915_TILING_X; else if (strcmp(optarg, "y") == 0) tiling = I915_TILING_Y; else if (strcmp(optarg, "none") == 0) tiling = I915_TILING_NONE; else abort(); break; case 'r': reps = atoi(optarg); if (reps < 1) reps = 1; break; default: break; } } handle = gem_create(fd, OBJECT_SIZE); switch (map) { case CPU: ptr = gem_mmap__cpu(fd, handle, 0, OBJECT_SIZE, PROT_WRITE); gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); break; case GTT: ptr = gem_mmap__gtt(fd, handle, OBJECT_SIZE, PROT_WRITE); gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); break; case WC: ptr = gem_mmap__wc(fd, handle, 0, OBJECT_SIZE, PROT_WRITE); gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); break; default: abort(); } gem_set_tiling(fd, handle, tiling, 512); if (dir == READ) { src = ptr; dst = buf; } else { src = buf; dst = ptr; } for (size = 1; size <= OBJECT_SIZE; size <<= 1) { igt_stats_t stats; int n; igt_stats_init_with_size(&stats, reps); for (n = 0; n < reps; n++) { struct timespec start, end; int page; clock_gettime(CLOCK_MONOTONIC, &start); switch (dir) { case CLEAR: memset(dst, 0, size); break; case FAULT: for (page = 0; page < OBJECT_SIZE; page += 4096) { uint32_t *x = (uint32_t *)ptr + page/4; page += *x; /* should be zero! */ } break; default: memcpy(dst, src, size); break; } clock_gettime(CLOCK_MONOTONIC, &end); igt_stats_push(&stats, elapsed(&start, &end)); } printf("%7.3f\n", igt_stats_get_trimean(&stats)/1000); igt_stats_fini(&stats); } return 0; }
static void rtprio(pthread_attr_t *attr, int prio) { #ifdef PTHREAD_EXPLICIT_SCHED struct sched_param param = { .sched_priority = 99 }; pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedpolicy(attr, SCHED_FIFO); pthread_attr_setschedparam(attr, ¶m); #endif } static double l_estimate(igt_stats_t *stats) { if (stats->n_values > 9) return igt_stats_get_trimean(stats); else if (stats->n_values > 5) return igt_stats_get_median(stats); else return igt_stats_get_mean(stats); } static double min_measurement_error(void) { struct timespec start, end; int n; clock_gettime(CLOCK_MONOTONIC, &start); for (n = 0; n < 1024; n++) clock_gettime(CLOCK_MONOTONIC, &end); return elapsed(&start, &end) / n; } int main(int argc, char **argv) { struct gem_busyspin *busy; struct sys_wait *wait; pthread_attr_t attr; int ncpus = sysconf(_SC_NPROCESSORS_ONLN); igt_stats_t cycles, mean, max; double min; int time = 10; int field = -1; int enable_gem_sysbusy = 1; int n, c; while ((c = getopt(argc, argv, "t:f:n")) != -1) { switch (c) { case 'n': /* dry run, measure baseline system latency */ enable_gem_sysbusy = 0; break; case 't': /* How long to run the benchmark for (seconds) */ time = atoi(optarg); if (time < 0) time = INT_MAX; break; case 'f': /* Select an output field */ field = atoi(optarg); break; default: break; } } /* Prevent CPU sleeps so that busy and idle loads are consistent. */ force_low_latency(); min = min_measurement_error(); busy = calloc(ncpus, sizeof(*busy)); pthread_attr_init(&attr); if (enable_gem_sysbusy) { for (n = 0; n < ncpus; n++) { bind_cpu(&attr, n); pthread_create(&busy[n].thread, &attr, gem_busyspin, &busy[n]); } } wait = calloc(ncpus, sizeof(*wait)); pthread_attr_init(&attr); rtprio(&attr, 99); for (n = 0; n < ncpus; n++) { igt_mean_init(&wait[n].mean); bind_cpu(&attr, n); pthread_create(&wait[n].thread, &attr, sys_wait, &wait[n]); } sleep(time); done = 1; igt_stats_init_with_size(&cycles, ncpus); if (enable_gem_sysbusy) { for (n = 0; n < ncpus; n++) { pthread_join(busy[n].thread, NULL); igt_stats_push(&cycles, busy[n].count); } } igt_stats_init_with_size(&mean, ncpus); igt_stats_init_with_size(&max, ncpus); for (n = 0; n < ncpus; n++) { pthread_join(wait[n].thread, NULL); igt_stats_push_float(&mean, wait[n].mean.mean); igt_stats_push_float(&max, wait[n].mean.max); } switch (field) { default: printf("gem_syslatency: cycles=%.0f, latency mean=%.3fus max=%.0fus\n", igt_stats_get_mean(&cycles), (igt_stats_get_mean(&mean) - min)/ 1000, (l_estimate(&max) - min) / 1000); break; case 0: printf("%.0f\n", igt_stats_get_mean(&cycles)); break; case 1: printf("%.3f\n", (igt_stats_get_mean(&mean) - min) / 1000); break; case 2: printf("%.0f\n", (l_estimate(&max) - min) / 1000); break; } return 0; }
int main(int argc, char **argv) { int fd = drm_open_any(); int size = 0; int busy = 0; int reps = 13; int c, n, s; while ((c = getopt (argc, argv, "bs:r:")) != -1) { switch (c) { case 's': size = atoi(optarg); break; case 'r': reps = atoi(optarg); if (reps < 1) reps = 1; break; case 'b': busy = true; break; default: break; } } if (size == 0) { for (s = 4096; s <= OBJECT_SIZE; s <<= 1) { igt_stats_t stats; igt_stats_init_with_size(&stats, reps); for (n = 0; n < reps; n++) { struct timespec start, end; uint64_t count = 0; clock_gettime(CLOCK_MONOTONIC, &start); do { for (c = 0; c < 1000; c++) { uint32_t handle; handle = gem_create(fd, s); gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); if (busy) make_busy(fd, handle); gem_close(fd, handle); } count += c; clock_gettime(CLOCK_MONOTONIC, &end); } while (end.tv_sec - start.tv_sec < 2); igt_stats_push_float(&stats, count / elapsed(&start, &end)); } printf("%f\n", igt_stats_get_trimean(&stats)); igt_stats_fini(&stats); } } else { for (n = 0; n < reps; n++) { struct timespec start, end; uint64_t count = 0; clock_gettime(CLOCK_MONOTONIC, &start); do { for (c = 0; c < 1000; c++) { uint32_t handle; handle = gem_create(fd, size); gem_set_domain(fd, handle, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); if (busy) make_busy(fd, handle); gem_close(fd, handle); } count += c; clock_gettime(CLOCK_MONOTONIC, &end); } while (end.tv_sec - start.tv_sec < 2); printf("%f\n", count / elapsed(&start, &end)); } } return 0; }
int main(int argc, char **argv) { int fd = drm_open_driver(DRIVER_INTEL); int domain = I915_GEM_DOMAIN_GTT; enum dir { READ, WRITE } dir = READ; void *buf = malloc(OBJECT_SIZE); uint32_t handle; int reps = 13; int c, size; while ((c = getopt (argc, argv, "D:d:r:")) != -1) { switch (c) { case 'd': if (strcmp(optarg, "cpu") == 0) domain = I915_GEM_DOMAIN_CPU; else if (strcmp(optarg, "gtt") == 0) domain = I915_GEM_DOMAIN_GTT; break; case 'D': if (strcmp(optarg, "read") == 0) dir = READ; else if (strcmp(optarg, "write") == 0) dir = WRITE; else abort(); break; case 'r': reps = atoi(optarg); if (reps < 1) reps = 1; break; default: break; } } handle = gem_create(fd, OBJECT_SIZE); for (size = 1; size <= OBJECT_SIZE; size <<= 1) { igt_stats_t stats; int n; igt_stats_init_with_size(&stats, reps); for (n = 0; n < reps; n++) { struct timespec start, end; gem_set_domain(fd, handle, domain, domain); clock_gettime(CLOCK_MONOTONIC, &start); if (dir == READ) gem_read(fd, handle, 0, buf, size); else gem_write(fd, handle, 0, buf, size); clock_gettime(CLOCK_MONOTONIC, &end); igt_stats_push(&stats, elapsed(&start, &end)); } printf("%7.3f\n", igt_stats_get_trimean(&stats)/1000); igt_stats_fini(&stats); } return 0; }