Beispiel #1
0
static void
print_counts(perf_event_desc_t *fds, int num_fds, const char *msg, FILE* fp)
{
	uint64_t val;
	uint64_t values[3];
	double ratio;
	int i;
	ssize_t ret;

#if 0
  fprintf(fp, "%s ------------------------------------\n", msg);
#else
  fprintf(fp, "method=%s", msg);
#endif

	/*
	 * now read the results. We use pfp_event_count because
	 * libpfm guarantees that counters for the events always
	 * come first.
	 */
	memset(values, 0, sizeof(values));

	for (i = 0; i < num_fds; i++) {

		ret = read(fds[i].fd, values, sizeof(values));
		if (ret < (ssize_t)sizeof(values)) {
			if (ret == -1)
				fprintf(stderr, "cannot read results: %s", strerror(errno));
			else
				warnx("could not read event%d", i);
		}
		/*
		 * scaling is systematic because we may be sharing the PMU and
		 * thus may be multiplexed
		 */
    int valid;
		val = perf_scale_valid(values, &valid);
    if (valid == 0) printf ("!i=%d, v0=%llu, v1=%llu, v2=%llu, val=%llu\n", i, values[0], values[1], values[2], val);
		ratio = perf_scale_ratio(values);

#if 0
		fprintf(fp, "%s %'20"PRIu64" %s (%.2f%% scaling, raw=%'"PRIu64", ena=%'"PRIu64", run=%'"PRIu64")\n",
			"-", // msg,
			val,
			fds[i].name,
			(1.0-ratio)*100.0,
		        values[0],
			values[1],
			values[2]);
#else
    fprintf (fp, " %s=%llu", fds[i].name, val); // valid ? val : 0);
#endif
	}
  fprintf (fp, "\n");
}
Beispiel #2
0
void read_cpu(int c)
{
	perf_event_desc_t *fds;
	uint64_t val, delta;
	double ratio;
	int i, j, n, ret;

	fds = all_fds[c];

	if (fds[0].fd == -1) {
		printf("CPU%d not monitored\n", c);
		return;
	}

	for(i=0, j = 0; i < options.num_groups; i++) {
		for(n = 0; n < options.nevents[i]; n++, j++) {

			ret = read(fds[j].fd, fds[j].values, sizeof(fds[j].values));
			if (ret != sizeof(fds[j].values)) {
				if (ret == -1)
					err(1, "cannot read event %s : %d", fds[j].name, ret);
				else {
					warnx("CPU%d G%-2d could not read event %s, read=%d", c, i, fds[j].name, ret);
					continue;
				}
			}
			/*
			 * scaling because we may be sharing the PMU and
			 * thus may be multiplexed
			 */
			delta = perf_scale_delta(fds[j].values, fds[j].prev_values);
			val = perf_scale(fds[j].values);
			ratio = perf_scale_ratio(fds[j].values);

			printf("CPU%-3d G%-2d %'20"PRIu64" %'20"PRIu64" %s (scaling %.2f%%, ena=%'"PRIu64", run=%'"PRIu64") %s\n",
				c,
				i,
				val,
				delta,
				fds[j].name,
				(1.0-ratio)*100,
				fds[j].values[1],
				fds[j].values[2],
				options.cgroup_name ? options.cgroup_name : "");

			fds[j].prev_values[0] = fds[j].values[0];
			fds[j].prev_values[1] = fds[j].values[1];
			fds[j].prev_values[2] = fds[j].values[2];

			if (fds[j].values[2] > fds[j].values[1])
				errx(1, "WARNING: time_running > time_enabled %"PRIu64"\n", fds[j].values[2] - fds[j].values[1]);
		}
	}
}
Beispiel #3
0
/* Same as stop above, but without the parameter
   for faster calling into. */
uint64_t *pfm_pause_counters() {
    int ret, i;
    uint64_t values[3];

    ret = prctl(PR_TASK_PERF_EVENTS_DISABLE);
    if (ret)
        fprintf(stderr, "prctl(disable) failed\n");

    /*
    * now read the results. We use pfp_event_count because
    * libpfm guarantees that counters for the events always
    * come first.
    */
    memset(values, 0, sizeof(values));

    for (i=0; i < num_fds; i++) {
        uint64_t val;
        double ratio;

        ret = read(fds[i].fd, values, sizeof(values));
        if (ret < sizeof(values)) {
            if (ret == -1)
                err(1, "cannot read results: %s", strerror(errno));
            else
                warnx("could not read event%d", i);
        }

        /*
         * scaling is systematic because we may be sharing the PMU and
         * thus may be multiplexed
         */
        val = perf_scale(values);
        ratio = perf_scale_ratio(values);

        counter_values[i] = val;
#ifdef VERBOSE
        printf("%'20"PRIu64" %s (%.2f%% scaling, ena=%'"PRIu64", run=%'"PRIu64")\n",
            val,
            fds[i].name,
            (1.0-ratio)*100.0,
            values[1],
            values[2]);
#endif
    }

    return counter_values;
}
Beispiel #4
0
void perfevent_read() {
  int i, ret;
  uint64_t values[3];
  /*
   * now read the results. We use pfp_event_count because
   * libpfm guarantees that counters for the events always
   * come first.
   */
  memset(values, 0, sizeof(values));

  fprintf(stderr, "============================ Tabulate Statistics ============================\n");
  for (i=0; i < perfevent_num_fds; i++) {
    fprintf(stderr, "%s	", perfevent_fds[i].name);
  }
  fprintf(stderr, "\n");
  for (i=0; i < perfevent_num_fds; i++) {
    uint64_t val;
    double ratio;

    ret = read(perfevent_fds[i].fd, values, sizeof(values));
    if (ret < sizeof(values)) {
      if (ret == -1)
        err(1, "cannot read results: %s", strerror(errno));
      else
        warnx("could not read event%d", i);
    }
    /*
     * scaling is systematic because we may be sharing the PMU and
     * thus may be multiplexed
     */
    val = perf_scale(values);
    ratio = perf_scale_ratio(values);

    if (ratio == 1.0)
      fprintf(stderr, "%lld	", (long long int) val);
    else
      if (ratio == 0.0)
        fprintf(stderr, "NO_VALUE	");
      else
        fprintf(stderr, "%lld-SCALED-%.2f%%	", (long long int) val, ratio*100.0);
  }
  fprintf(stderr, "\n=============================================================================\n");
}
Beispiel #5
0
static void
print_counts(perf_event_desc_t *fds, int num, int do_delta)
{
	uint64_t values[3];
	ssize_t ret;
	int i;

	/*
	 * now simply read the results.
	 */
	for(i=0; i < num; i++) {
		uint64_t val;
		double ratio;

		ret = read(fds[i].fd, values, sizeof(values));
		if (ret < (ssize_t)sizeof(values)) {
			if (ret == -1)
				err(1, "cannot read values event %s", fds[i].name);
			else
				warnx("could not read event%d", i);
		}

		/*
		 * scaling because we may be sharing the PMU and
		 * thus may be multiplexed
		 */
		fds[i].prev_value = fds[i].value;
		fds[i].value = val = perf_scale(values);
		ratio = perf_scale_ratio(values);

		val = do_delta ? (val - fds[i].prev_value): val;

		if (ratio == 1.0)
			printf("%20"PRIu64" %s\n", val, fds[i].name);
		else
			if (ratio == 0.0)
				printf("%20"PRIu64" %s (did not run: incompatible events, too many events in a group, competing session)\n", val, fds[i].name);
			else
				printf("%20"PRIu64" %s (scaled from %.2f%% of time)\n", val, fds[i].name, ratio*100.0);

	}
}
Beispiel #6
0
static void
fetch_counts(perf_event_desc_t *fds, int num_fds)
{
  if (begins == 0) {
    begins = (uint64_t*) malloc(num_fds * sizeof(uint64_t));
    memset(begins, 0, num_fds * sizeof(uint64_t));
  }

	uint64_t val;
	uint64_t values[3];
	double ratio;
	int i;
	ssize_t ret;

	/*
	 * now read the results. We use pfp_event_count because
	 * libpfm guarantees that counters for the events always
	 * come first.
	 */
	memset(values, 0, sizeof(values));

	for (i = 0; i < num_fds; i++) {
		ret = read(fds[i].fd, values, sizeof(values));
		if (ret < (ssize_t)sizeof(values)) {
			if (ret == -1)
				fprintf(stderr, "cannot read results: %s", strerror(errno));
			else
				warnx("could not read event%d", i);
		}
		/*
		 * scaling is systematic because we may be sharing the PMU and
		 * thus may be multiplexed
		 */
    int valid = 0;
		val = perf_scale_valid(values, &valid);
    if (valid == 0) printf ("@i=%d, v0=%llu, v1=%llu, v2=%llu, val=%llu\n", i, values[0], values[1], values[2], val);
		ratio = perf_scale_ratio(values);

    begins[i] = val;
  }
}
Beispiel #7
0
static void
print_counts(perf_event_desc_t *fds, int num)
{
	double ratio;
	uint64_t val, delta;
	int i;

	read_groups(fds, num);

	for(i=0; i < num; i++) {

		val   = perf_scale(fds[i].values);
		delta = perf_scale_delta(fds[i].values, fds[i].prev_values);
		ratio = perf_scale_ratio(fds[i].values);

		/* separate groups */
		if (perf_is_group_leader(fds, i))
			putchar('\n');

		if (options.print)
			printf("%'20"PRIu64" %'20"PRIu64" %s (%.2f%% scaling, ena=%'"PRIu64", run=%'"PRIu64")\n",
				val,
				delta,
				fds[i].name,
				(1.0-ratio)*100.0,
				fds[i].values[1],
				fds[i].values[2]);
		else
			printf("%'20"PRIu64" %s (%.2f%% scaling, ena=%'"PRIu64", run=%'"PRIu64")\n",
				val,
				fds[i].name,
				(1.0-ratio)*100.0,
				fds[i].values[1],
				fds[i].values[2]);

		fds[i].prev_values[0] = fds[i].values[0];
		fds[i].prev_values[1] = fds[i].values[1];
		fds[i].prev_values[2] = fds[i].values[2];
	}
}
static void
print_counts(perf_event_desc_t *fds, int num, int do_delta)
{
	ssize_t ret;
	int i;

	/*
	 * now simply read the results.
	 */
	for(i=0; i < num; i++) {
		uint64_t val;
		double ratio;

		ret = read(fds[i].fd, fds[i].values, sizeof(fds[i].values));
		if (ret < (ssize_t)sizeof(fds[i].values)) {
			if (ret == -1)
				err(1, "cannot read values event %s", fds[i].name);
			else
				warnx("could not read event%d", i);
		}

		val = perf_scale(fds[i].values);
		ratio = perf_scale_ratio(fds[i].values);

		val = do_delta ? perf_scale_delta(fds[i].values, fds[i].prev_values) : val;

		fds[i].prev_values[0] = fds[i].values[0];
		fds[i].prev_values[1] = fds[i].values[1];
		fds[i].prev_values[2] = fds[i].values[2];

		if (ratio == 1.0)
			printf("%20"PRIu64" %s\n", val, fds[i].name);
		else
			if (ratio == 0.0)
				printf("%20"PRIu64" %s (did not run: incompatible events, too many events in a group, competing session)\n", val, fds[i].name);
			else
				printf("%20"PRIu64" %s (scaled from %.2f%% of time)\n", val, fds[i].name, ratio*100.0);
	}
}
Beispiel #9
0
static void
measure(void)
{
	perf_event_desc_t *fds = NULL;
	int num_fds = 0;
	uint64_t values[3];
	ssize_t n;
	int i, ret;
	int pr[2], pw[2];
	pid_t pid;
	char cc = '0';

	ret = pfm_initialize();
	if (ret != PFM_SUCCESS)
		err(1, "cannot initialize libpfm");

	if (options.cpu == -1) {
		srandom(getpid());
		options.cpu = random() % sysconf(_SC_NPROCESSORS_ONLN);
	}

	ret = pipe(pr);
	if (ret)
		err(1, "cannot create read pipe");

	ret = pipe(pw);
	if (ret)
		err(1, "cannot create write pipe");

	ret = perf_setup_list_events(options.events, &fds, &num_fds);
	if (ret || !num_fds)
		exit(1);

	for(i=0; i < num_fds; i++) {
		fds[i].hw.disabled = 1;
		fds[i].hw.read_format = PERF_FORMAT_SCALE;

		fds[i].fd = perf_event_open(&fds[i].hw, 0, -1, -1, 0);
		if (fds[i].fd == -1)
			err(1, "cannot open event %d", i);
	}

	/*
 	 * Pin to CPU0, inherited by child process. That will enforce
 	 * the ping-pionging and thus stress the PMU context switch 
 	 * which is what we want
 	 */
	ret = pin_cpu(getpid(), options.cpu);
	if (ret)
		err(1, "cannot pin to CPU%d", options.cpu);

	printf("Both processes pinned to CPU%d, running for %d seconds\n", options.cpu, options.delay);

	/*
 	 * create second process which is not monitoring at the moment
 	 */
	switch(pid=fork()) {
		case -1:
			err(1, "cannot create child\n");
		case 0:
			/* do not inherit session fd */
			for(i=0; i < num_fds; i++)
				close(fds[i].fd);
			/* pr[]: write master, read child */
			/* pw[]: read master, write child */
			close(pr[1]); close(pw[0]);
			do_child(pr[0], pw[1]);
			exit(1);
	}

	close(pr[0]);
	close(pw[1]);

	/*
	 * Let's roll now
	 */
	prctl(PR_TASK_PERF_EVENTS_ENABLE);
	signal(SIGALRM, sig_handler);
	alarm(options.delay);

	/*
	 * ping pong loop
	 */
	while(!quit) {
		n = write(pr[1], "c", 1);
		if (n < 1)
			err(1, "write failed");
		n = read(pw[0], &cc, 1);
		if (n < 1)
			err(1, "read failed");
	}

	prctl(PR_TASK_PERF_EVENTS_DISABLE);

	for(i=0; i < num_fds; i++) {
		uint64_t val;
		double ratio;

		ret = read(fds[i].fd, values, sizeof(values));
		if (ret == -1)
			err(1,"pfm_read error");
		if (ret != sizeof(values))
			errx(1, "did not read correct amount %d", ret);

		val = perf_scale(values);
		ratio = perf_scale_ratio(values);

		if (ratio == 1.0)
			printf("%20"PRIu64" %s\n", val, fds[i].name);
		else
			if (ratio == 0.0)
				printf("%20"PRIu64" %s (did not run: competing session)\n", val, fds[i].name);
			else
				printf("%20"PRIu64" %s (scaled from %.2f%% of time)\n", val, fds[i].name, ratio*100.0);
	}
	/*
	 * kill child process
	 */
	kill(SIGKILL, pid);

	/*
 	 * close pipes
 	 */
	close(pr[1]);
	close(pw[0]);
	/*
	 * and destroy our session
	 */
	for(i=0; i < num_fds; i++)
		close(fds[i].fd);

	perf_free_fds(fds, num_fds);

	/* free libpfm resources cleanly */
	pfm_terminate();
}