Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

accurate cpu time on windows

prop_design
New Contributor I
908 Views

hi,

 

it seems like the CPU_TIME function on windows might only be good to milliseconds. it's making a test program i'm trying to create a problem. is there some trick to get that to microseconds. even better would be nanoseconds. any version of fortran would do. if it is possible, could you post the code for that, so i can copy it into my code. i think if you are on linux CPU_TIME is automatically good to microseconds However, I'm not sure.

 

anthony

0 Kudos
11 Replies
JohnNichols
Valued Contributor III
899 Views

I have this problem with the ST.COM accelerometers.  You need to use the ticks functions with a stop watch as in C# and then you are ok.  You might have to call C#.

Any Windows clock is lucky to be close to 10 ms and I would not trust it.  

There a lot of examples on here and in the WWW to match Fortran to C# and there are a lot of stop watch examples in C#.  You will need to hunt. 

 

0 Kudos
Steve_Lionel
Honored Contributor III
885 Views

The Windows multimedia timers can be used for higher resolution. Multimedia Timers - Win32 apps | Microsoft Learn

0 Kudos
JohnNichols
Valued Contributor III
871 Views

Stop watch and multimedia timers 

 

This article provides a good explanation as to the two uses.  Note they are not the same.  

0 Kudos
jimdempseyatthecove
Honored Contributor III
837 Views

Use SYSTEM_CLOCK with INTEGER(8) arguments for higher precision.

Or better write interfaces to call QueryPerformanceCounter and QueryPerformanceFrequency.

These may already be in kernel32.mod/f90

Note, these are based on the Frontside Bus frequency

Programming at the application level is not the same as having a hardware event feature together with a true event handler as these are available inside a driver that runs at system level.

While you can get the tick count from the CPU into your application, for example to get a high precision elapse time, you would not know that your elapse time (of your code) was not interceded (extended by) other activity on the system. IOW you need to make multiple measurements and discard anomalous readings then make an average of the rest.

Trying to use application level software elapse time method to trigger a "take a sample now" function may work sufficiently well most of the time, but expect to get bit in the behind once in a while. 

Jim Dempsey

 

 

0 Kudos
JohnNichols
Valued Contributor III
816 Views

If you record the time for a series of constant events, ie loop time on a program and then do a linear regression on the data you will get a good idea of the rates.  I am using this technique with the ST.COM accelerometers as their tick count is all over the place.   The recording frequency on identical NUCs running everything the same is 1200 to 1500 reads per second.  I cannot control it - I can just measure it.  There are no serial numbers on each device so I cannot calibrate once.  

Makes FFT a pain, but this is why we went to a good physics school.  

Many years ago I was learning assembler, for a few days until I worked out there is a reason one learns Fortran, but there was an example machine gun noise generator, and so I looked on line and found the book from the 80's uploaded by the author.  

 

I liked his style.  Just out of interest would the code work on a modern machine or is it to DOS?  

 

 

0 Kudos
prop_design
New Contributor I
807 Views

Hi,

 

Thanks for the insights. There does look to be more accurate ways to measure time on Windows. However, they aren't with Fortran. So I'm not going to worry about it. It's becoming way to much hassle for what I was looking to do. Everything I write is Fortran 77 running on Windows. It looks like that limits your memory capacity a lot. However, that's not an issue for me. Accurate time readings seems to be another issue. If I was on Linux, both issues would be much less and workable via Fortran 77. All the programs run from the Windows command prompt. In the old days, that would have been DOS. However, I think it's no longer DOS.

 

Edit, some of the Fortran functions I'm using aren't from Fortran 77 though. I generally use whatever the compiler allows in that regard. So stuff like FLOOR, CPU_TIME, SYSTEM_CLOCK, etc... Aren't from Fortran 77. I just write in that language, since it's what I learned. Never had a need to use anything else.

0 Kudos
prop_design
New Contributor I
807 Views

I gave the SYSTEM_CLOCK a try. It may be a little better. Hard for me to tell exactly. I had seen it in the manual, however, I had been using CPU_TIME and hadn't previously found a reason to use something else. Most of the solutions people suggested are way above my head.

 

I'm having a lot of issues with trying to create what I thought would be a simple test code. I may have to give up on it. Not worth explaining them on here. I appreciate the feedback though.

0 Kudos
prop_design
New Contributor I
784 Views

i finished evaluating both CPU_TIME and SYSTEM_CLOCK. I'm not seeing any substantial difference. neither seems to be accurate enough for this test code. so i give up. but i appreciate all the suggestions.

0 Kudos
mecej4
Honored Contributor III
780 Views

The documentation for SYSTEM_CLOCK says:

If the type is INTEGER(1), count_rate is 0. If the type is INTEGER(2), count_rate is 1000. If the type is INTEGER(4) or REAL(4), count_rate is 10000. If the type is INTEGER(8), REAL(8), or REAL(16), count_rate is 1000000.

Thus, unless you selected the variable that represents count_rate to be INTEGER(8), etc., you would not get the higher precision that you seek. What types did you use for the arguments that you passed to SYSTEM_CLOCK?

0 Kudos
prop_design
New Contributor I
775 Views

yeah i read that. i did integer*8

0 Kudos
prop_design
New Contributor I
697 Views

I found an old post on this forum, that included Fortran subroutines of various time methods. I also saw threads where people were asking to just improve CPU_TIME. I would second my vote on that. I don't understand what this subroutine does or if it's programmed right. However, I got it to work with my code and it does seem to be a little more accurate than the CPU_TIME or SYSTEM_CLOCK. Not earth shatteringly different, in my tests anyway, but a little bit better.

 

Update; I made a few minor mods to the code I posted previously.

 

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C     WIN API ROUTINE
C
      SUBROUTINE QUERYPERFORM(TIME)
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C      USE IFWIN, ONLY: T_LARGE_INTEGER, QUERYPERFORMANCECOUNTER,
C     &                 QUERYPERFORMANCEFREQUENCY
C
      USE IFWIN
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
      REAL*8, INTENT (OUT) :: TIME
C
      INTEGER*8 NUM
C
      REAL*8 FREQ
C
      TYPE(T_LARGE_INTEGER) :: ARG
C
      LOGICAL*8 LL
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
      FREQ = -1.0D0
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
      IF ( FREQ .LT. 0.0D0 ) THEN
C
C     CYCLE RATE
C
        LL = QUERYPERFORMANCEFREQUENCY(ARG)
C
        NUM = TRANSFER(ARG,NUM)
C
        FREQ = 1.0D0 / REAL ( NUM , 8 )
C
        WRITE (*,*)
C
        WRITE (*,'(1X,A)')
     &   'QUERYPERFORMANCE INITIALIZATION'
C
        WRITE (*,'(1X,A,G0.3)')
     &   'QUERYPERFORMANCE CLOCK SPEED (GHZ) = ', FREQ * 1.0D9
C
      END IF
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C     CYCLE COUNT; ASSUME LL IS OK
C
      LL = QUERYPERFORMANCECOUNTER(ARG)
C
      NUM = TRANSFER(ARG,NUM)
C
      TIME = FREQ * REAL ( NUM , 8 )
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
      END SUBROUTINE QUERYPERFORM
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

 

0 Kudos
Reply