Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

Fortran Programming Language

rdtsc for x86-64 (and IA-32)


With gfortran running on x86-64, I finally got around
to writing the routine to return the value of the rdtsc
(time stamp counter).

rdtsc was designed for IA32 and returns the 64 bit value
in the EAX and EDX registers.  This is conveniently
the right place for the return value of a 64 bit integer
for most IA32 calling conventions.

For x86-64 a function return value is in the 64 bit
RAX register, but rdtsc still returns the value in
EAX and EDX.  I now have the following running with
gfortran/x86-64/Linux:

         .file   "rdtsc.s"
         .text
.globl rdtsc_
         .type   rdtsc_, @function
rdtsc_:
         rdtsc
         movl %eax,%ecx
         movl %edx,%eax
         shlq $32,%rax
         addq %rcx,%rax
         ret
         .size   rdtsc_, .-rdtsc_

It should be declared as INTEGER*8 rdtsc, or your preferred way
of declaring functions that return 64 bit integers.

This was formed by compiling a simple function with the -S option,
removing unneeded code and data from the generated rdtsc.s file,
adding the appropriate instruction, and then compiling it with

gfortran -c rdtsc.s

For 32 bit code, it should be something like:

         .file   "rdtsc.s"
         .text
.globl rdtsc_
         .type   rdtsc_, @function
rdtsc_:
         rdtsc
         ret
         .size   rdtsc_, .-rdtsc_

but I haven't tried this one, yet.

(I have gfortran on an x86-64 machine and g95 on an IA32 machine.)

You can test it with a program like:

       integer*8 rdtsc,t0,t1
       t0=rdtsc(1)
       do 1 i=1,1000000000
1     continue
       t1=rdtsc(2)
       print *,t1-t0
       write(*,'(z18,z18)') t0,t1
       stop
       end

gfortran seems to generate seven instructions for the DO
loop, the first two instruction skip the loop if
1 is greater than 1000000000 (it never is).  It would
seem that it could use the same two instruction test
inside the loop, but it uses seven instead.  I suppose,
though, it optimizes for loops with statements in them.

         cmpl    $1000000000, -12(%rbp)
         jg      .L2
.L3:
         cmpl    $1000000000, -12(%rbp)
         sete    %al
         movzbl  %al, %eax
         addl    $1, -12(%rbp)
         testl   %eax, %eax
         jne     .L2
         jmp     .L3
.L2:

-- glen

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc