Initial profiling results (was: Re: -O2 loop problems)

Anthony Green green@redhat.com
Thu Jan 4 16:42:00 GMT 2001


On Thursday, January 04, 2001 3:26 PM, Jeff Sturm [SMTP:jeff.sturm@appnet.com] 
wrote:
> I'd love to know how to get at similar hardware event counters on x86. I'm
> not
> familiar with any free tools for that arch.

Here are two ideas. On Red Hat Linux 7 you can use a new set of functions in 
glibc which are part of POSIX. They provide a clean interface to a possibly 
existing CPU counter. The results are reported in nsecs. Get a RH7 system 
(with the i686 version of glibc), look in <time.h> for clock_getcpuclockid() 
and timer_gettime(), timer_*().
Then there's this old hack. Compile the following to measure.so and run your 
program like so...
$ LD_PRELOAD=measure.so MONITORPROF_OUTPUT=output.txt MyProgram
Then read output.txt. This one measures _Jv_MonitorEnter. (Thanks to Ulrich 
Drepper - my source of all things glibc-ish)
#define _GNU_SOURCE
#include <ctype.h>
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static int fd = -1;
static int (*monitorenter) (void *obj);
static void
constr (void)
{
 const char *fname;
 if (fd != -1)
 return;
 fname = getenv ("MONITORPROF_OUTPUT");
 if (fname != NULL && *fname != '0円')
 {
 int procfd;
 fd = creat (fname, 0666);
 /* Get the processor frequency. */
 procfd = open ("/proc/cpuinfo", O_RDONLY);
 if (procfd != -1)
	{
	 char buf[2000];
	 ssize_t n;
	 if ((n = read (procfd, buf, sizeof (buf))) > 0)
	 {
	 char *cpuhz;
	 buf[sizeof (buf) - 1] = '0円';
	 cpuhz = strstr (buf, "cpu MHz");
	 if (cpuhz != NULL)
		{
		 struct iovec iov[2];
		 cpuhz += 7;
		 iov[0].iov_base = (void *) "Processor clock: ";
		 iov[0].iov_len = strlen (iov[0].iov_base);
		 while (! isdigit (*cpuhz))
		 ++cpuhz;
		 iov[1].iov_base = cpuhz;
		 while (*cpuhz != '0円' && *cpuhz != '\n')
		 ++cpuhz;
		 *cpuhz++ = '\n';
		 iov[1].iov_len = cpuhz - (char *) iov[1].iov_base;
		 writev (fd, iov, 2);
		}
	 }
	 close (procfd);
	}
 }
 monitorenter = dlsym (RTLD_NEXT, "_Jv_MonitorEnter");
 if (monitorenter == NULL)
 abort ();
}
int
_Jv_MonitorEnter (void *o)
{
 char buf[300];
 int length;
 unsigned long long int before;
 unsigned long long int after;
 int result;
 asm volatile ("rdtsc" : "=A" (before));
 if (! monitorenter)
 if (fd == -1)
	 constr ();
 result = monitorenter (o);
 asm volatile ("rdtsc" : "=A" (after));
 if (fd != -1)
 {
 length = sprintf (buf, "%20llu\n",
			(unsigned long long int) after - before);
 write (fd, buf, length);
 }
 return result;
}
/*
 * Local variables:
 * compile-command: "gcc -shared -O2 -Wall -fPIC -o measure.so measure.c -ldl"
 * End:
 */


More information about the Java mailing list

AltStyle によって変換されたページ (->オリジナル) /