Computer Chess Club Archives


Search

Terms

Messages

Subject: Strange timing problem wit performance counter (for Windows experts?)

Author: Dieter Buerssner

Date: 12:56:28 11/07/04


One user of my engine reported regular forfeits on time. It turned out, that on
his computer my timing code does not work well. The QueryPerformanceCounter
function just seems to return wrong results, while GetTickCount works as
expected. In Yace, I use the former function if available, and the later only as
fallback. I actually forgot why, but I think it had some reason once :-)

Can anybody explain, why QueryPerformanceCounter returns wrong results. The
following program should print a line about every second, and both reported
times should be about equal. They even are on the computer of this user. I
suggested to try under heavy load. He tried the program again, during an engine
match, Virus scan, .... And now, the PerformanceCounter clock ran much slower.
Computer was a Dell P4. On my noname P4, 2.53 GHz, no HT, everything works as
expected. I suspect under most computers, it does - otherwise I should get more
reports for losses on time. I remember one other report some years ago, with
time problems. The computer was a dual, I forgot more details. I think, I did
not investigate very carefully at the time.

BTW. Is the PerformanceCounter stuff implemented via the CPU counter on some
computers and via something else on other computers? I get

freq 3.579545e+006 1/s 2.793651e-007 s per tick
PerfCount  TickCount
    1.020      1.021
    2.021      2.023
[and so on until 60]

So it is clearly not the CPU frequency. On the user comp freq was reported as
3.19e9 - this might be the CPU frequency. At least the factor of 1000 difference
to my computer suggests some basic difference in the implementation of the
function.

On the user computer under heavy load the Perfcount clock ran only at half the
speed under heavy load, and at normaly speed unloaded.

Do any other engines use the PerformanceCounter stuff for timing? Did you hear
of similar problems? Is there perhaps even a solution (from inside the engine)?

Regards,
Dieter

Compile with cl test.c or gcc test.c or icc test.c. Windows specific code ...

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

static LARGE_INTEGER init_pc;
static unsigned long init_tc;
static double t_per_sec; /* Should be sec_per_tick ... */

void init(void)
{
  LARGE_INTEGER freq;
  if (QueryPerformanceFrequency(&freq) == 0)
  {
    fprintf(stderr, "Oops, QueryPerformanceFrequency returned 0\n");
    exit(1);
  }
  t_per_sec = 1.0/freq.QuadPart;
  printf("freq %.6e 1/s %.6e s per tick\n", (double)freq.QuadPart, t_per_sec);
  if (QueryPerformanceCounter(&init_pc) == 0)
  {
    fprintf(stderr, "Oops, QueryPerformanceCounter returned 0\n");
    exit(1);
  }
  init_tc = GetTickCount();
}

double pc_time(void)
{
  LARGE_INTEGER cnt;
  if (QueryPerformanceCounter(&cnt) == 0)
  {
    fprintf(stderr, "Oops, QueryPerformanceCounter returned 0\n");
    exit(1);
  }
  return (cnt.QuadPart - init_pc.QuadPart)*t_per_sec;
}

double tc_time(void)
{
  return (GetTickCount()-init_tc)*1e-3;
}

int main(void)
{
  double t_pc, t_tc;

  init();
  printf("PerfCount  TickCount\n");
  do
  {
    Sleep(1000);
    t_pc = pc_time();
    t_tc = tc_time();
    printf("  %7.3f    %7.3f\n", t_pc, t_tc);
  }
  while (t_tc <= 60);
  return 0;
}





This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.