All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eugeni Dodonov <eugeni@dodonov.net>
To: intel-gfx@lists.freedesktop.org
Cc: Eugeni Dodonov <eugeni.dodonov@intel.com>
Subject: [PATCH 5/6] intel_gpu_top: support non-interactive mode
Date: Mon,  5 Sep 2011 17:19:32 -0300	[thread overview]
Message-ID: <1315253973-18950-6-git-send-email-eugeni@dodonov.net> (raw)
In-Reply-To: <1315253973-18950-1-git-send-email-eugeni@dodonov.net>

From: Eugeni Dodonov <eugeni.dodonov@intel.com>

This patch adds support for non-interactive mode, invoked by running with
'-o output' switch. In this case, no interactive output is being
performed, but the execution statistics are being saved into the output
file.

The output file is generated in both human and gnuplot-readable format.

Unlike interactive mode, where non-supported pipes and non-active
registers are skipped, the content of such pipes and registers is recorded
into the log file to simplify parsing and standardize the list of columns.

Also, unlike interactive mode, the registers are not sorted according to
the usage - this way, their variation over time can be analysed offline.

Signed-off-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
---
 man/intel_gpu_top.1   |    3 +
 tools/intel_gpu_top.c |  150 +++++++++++++++++++++++++++++++++++-------------
 2 files changed, 112 insertions(+), 41 deletions(-)

diff --git a/man/intel_gpu_top.1 b/man/intel_gpu_top.1
index 2cbbec9..bca83f0 100644
--- a/man/intel_gpu_top.1
+++ b/man/intel_gpu_top.1
@@ -16,6 +16,9 @@ privilege to map the graphics device.
 .B -s [samples per second]
 number of samples to acquire per second
 .TP
+.B -o [output file]
+run non-interactively and collect usage statistics to [file]
+.TP
 .B -h
 show usage notes
 .PP
diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
index e2dd173..88f7157 100644
--- a/tools/intel_gpu_top.c
+++ b/tools/intel_gpu_top.c
@@ -373,24 +373,39 @@ static void ring_sample(struct ring *ring)
 	ring->full += full;
 }
 
+static void ring_print_header(FILE *out, struct ring *ring)
+{
+    fprintf(out, "%.6s%%\tops\t",
+            ring->name
+          );
+}
+
 static void ring_print(struct ring *ring, unsigned long samples_per_sec,
 		FILE *output)
 {
 	int samples_to_percent_ratio, percent, len;
 
-	if (!ring->size)
-		return;
-
 	/* Calculate current value of samples_to_percent_ratio */
 	samples_to_percent_ratio = (ring->idle * 100) / samples_per_sec;
 	percent = 100 - samples_to_percent_ratio;
-	len = fprintf(output, "%25s busy: %3d%%: ", ring->name, percent);
-	print_percentage_bar (percent, len);
-	fprintf(output, "%24s space: %d/%d (%d%%)\n",
-	       ring->name,
-	       (int)(ring->full / samples_per_sec),
-	       ring->size,
-	       (int)((ring->full / samples_to_percent_ratio) / ring->size));
+
+	if (output == stdout) {
+		if (!ring->size)
+			return;
+
+		len = fprintf(output, "%25s busy: %3d%%: ", ring->name, percent);
+		print_percentage_bar (percent, len);
+		fprintf(output, "%24s space: %d/%d (%d%%)\n",
+			   ring->name,
+			   (int)(ring->full / samples_per_sec),
+			   ring->size,
+			   (int)((ring->full / samples_to_percent_ratio) / ring->size));
+	} else {
+		fprintf(output, "%3d\t%d\t",
+			   (ring->size) ? 100 - ring->idle / samples_to_percent_ratio : -1,
+			   (ring->size) ? (int)(ring->full / samples_per_sec) : -1
+			   );
+	}
 }
 
 static void
@@ -402,6 +417,7 @@ usage(const char *appname)
 			"\n"
 			"The following parameters apply:\n"
 			"[-s <samples>]       samples per seconds (default %d)\n"
+            "[-o <file>]          output to file (default to stdio)\n"
 			"[-h]                 show this help screen\n"
 			"\n",
 			appname,
@@ -429,9 +445,11 @@ int main(int argc, char **argv)
 	int i, ch;
 	int samples_per_sec = SAMPLES_PER_SEC;
 	FILE *output = stdout;
+	double elapsed_time=0;
+	int print_headers=1;
 
 	/* Parse options? */
-	while ((ch = getopt(argc, argv, "s:h")) != -1)
+	while ((ch = getopt(argc, argv, "s:o:h")) != -1)
 	{
 		switch (ch)
 		{
@@ -441,6 +459,13 @@ int main(int argc, char **argv)
 						  exit(1);
 					  }
 					  break;
+			case 'o': output = fopen(optarg, "w");
+					  if (!output)
+					  {
+						  perror("fopen");
+						  exit(1);
+					  }
+					  break;
 			case 'h':
 				  usage(argv[0]);
 				  exit(0);
@@ -493,7 +518,7 @@ int main(int argc, char **argv)
 
 	for (;;) {
 		int j;
-		unsigned long long t1, ti, tf;
+		unsigned long long t1, ti, tf, t2;
 		unsigned long long def_sleep = 1000000 / samples_per_sec;
 		unsigned long long last_samples_per_sec = samples_per_sec;
 		char clear_screen[] = {0x1b, '[', 'H',
@@ -564,39 +589,82 @@ int main(int argc, char **argv)
 		if (max_lines >= num_instdone_bits)
 			max_lines = num_instdone_bits;
 
-		fprintf(output, "%s", clear_screen);
-
-		print_clock_info(pci_dev);
-
-		ring_print(&render_ring, last_samples_per_sec, output);
-		ring_print(&bsd_ring, last_samples_per_sec, output);
-		ring_print(&bsd6_ring, last_samples_per_sec, output);
-		ring_print(&blt_ring, last_samples_per_sec, output);
-
-		fprintf(output, "\n%30s  %s\n", "task", "percent busy");
-		for (i = 0; i < max_lines; i++) {
-			if (top_bits_sorted[i]->count > 0) {
-				percent = (top_bits_sorted[i]->count * 100) /
-					last_samples_per_sec;
-				len = fprintf(output, "%30s: %3d%%: ",
-					     top_bits_sorted[i]->bit->name,
-					     percent);
-				print_percentage_bar (percent, len);
-			} else {
-				fprintf(output, "%*s", PERCENTAGE_BAR_END, "");
+        t2 = gettime();
+        elapsed_time += (t2 - t1) / 1000000.0;
+
+		if (output == stdout) {
+			fprintf(output, "%s", clear_screen);
+			print_clock_info(pci_dev);
+
+			ring_print(&render_ring, last_samples_per_sec, output);
+			ring_print(&bsd_ring, last_samples_per_sec, output);
+			ring_print(&bsd6_ring, last_samples_per_sec, output);
+			ring_print(&blt_ring, last_samples_per_sec, output);
+
+			fprintf(output, "\n%30s  %s\n", "task", "percent busy");
+			for (i = 0; i < max_lines; i++) {
+				if (top_bits_sorted[i]->count > 0) {
+					percent = (top_bits_sorted[i]->count * 100) /
+						last_samples_per_sec;
+					len = fprintf(output, "%30s: %3d%%: ",
+							 top_bits_sorted[i]->bit->name,
+							 percent);
+					print_percentage_bar (percent, len);
+				} else {
+					fprintf(output, "%*s", PERCENTAGE_BAR_END, "");
+				}
+
+				if (i < STATS_COUNT && HAS_STATS_REGS(devid)) {
+					fprintf(output, "%13s: %llu (%lld/sec)",
+						   stats_reg_names[i],
+						   stats[i],
+						   stats[i] - last_stats[i]);
+					last_stats[i] = stats[i];
+				} else {
+					if (!top_bits_sorted[i]->count)
+						break;
+				}
+				fprintf(output, "\n");
+			}
+		} else {
+			/* Print headers for columns at first run */
+			if (print_headers) {
+				fprintf(output, "# time\t");
+				ring_print_header(output, &render_ring);
+				ring_print_header(output, &bsd_ring);
+				ring_print_header(output, &bsd6_ring);
+				ring_print_header(output, &blt_ring);
+				for (i = 0; i < MAX_NUM_TOP_BITS; i++) {
+					if (i < STATS_COUNT && HAS_STATS_REGS(devid)) {
+						fprintf(output, "%.6s\t",
+							   stats_reg_names[i]
+							   );
+					}
+					if (!top_bits[i].count)
+						continue;
+				}
+				fprintf(output, "\n");
+				print_headers = 0;
 			}
 
-			if (i < STATS_COUNT && HAS_STATS_REGS(devid)) {
-				fprintf(output, "%13s: %llu (%lld/sec)",
-				       stats_reg_names[i],
-				       stats[i],
-				       stats[i] - last_stats[i]);
-				last_stats[i] = stats[i];
-			} else {
-				if (!top_bits_sorted[i]->count)
-					break;
+			/* Print statistics */
+			fprintf(output, "%.2f\t", elapsed_time);
+			ring_print(&render_ring, last_samples_per_sec, output);
+			ring_print(&bsd_ring, last_samples_per_sec, output);
+			ring_print(&bsd6_ring, last_samples_per_sec, output);
+			ring_print(&blt_ring, last_samples_per_sec, output);
+
+			for (i = 0; i < MAX_NUM_TOP_BITS; i++) {
+				if (i < STATS_COUNT && HAS_STATS_REGS(devid)) {
+					fprintf(output, "%lu\t",
+						   stats[i] - last_stats[i]);
+					last_stats[i] = stats[i];
+				}
+					if (!top_bits[i].count)
+						continue;
 			}
 			fprintf(output, "\n");
+			fflush(output);
 		}
 
 		for (i = 0; i < num_instdone_bits; i++) {
-- 
1.7.6.1

  parent reply	other threads:[~2011-09-05 20:20 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-05 20:19 [PATCH 0/6] additional intel_gpu_top profiling features Eugeni Dodonov
2011-09-05 20:19 ` [PATCH 1/6] intel_gpu_top: account for time spent in syscalls Eugeni Dodonov
2011-09-05 20:19 ` [PATCH 2/6] intel_gpu_top: suport command line parameters and variable samples per second Eugeni Dodonov
2011-09-05 21:44   ` Chris Wilson
2011-09-05 22:16     ` Eugeni Dodonov
2011-09-05 20:19 ` [PATCH 3/6] intel_gpu_tool: initial support for non-screen output Eugeni Dodonov
2011-09-05 22:56   ` Łukasz Kuryło
2011-09-05 23:48     ` Łukasz Kuryło
2011-09-06  0:05     ` Eugeni Dodonov
2011-09-05 20:19 ` [PATCH 4/6] intel_gpu_top: initialize monitoring statistics at startup Eugeni Dodonov
2011-09-05 20:19 ` Eugeni Dodonov [this message]
2011-09-05 20:19 ` [PATCH 6/6] intel_gpu_top: support profiling user-specified commands Eugeni Dodonov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1315253973-18950-6-git-send-email-eugeni@dodonov.net \
    --to=eugeni@dodonov.net \
    --cc=eugeni.dodonov@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.