This is the mail archive of the java-discuss@sources.redhat.com mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

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


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:
 */




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]