From: Alexandre Naaman (naaman++at++laplace.engr.sgi.com)
Date: 10/23/2003 11:49:45
On Wed, 22 Oct 2003, Dorosky, Christopher G wrote:
Hi guys,
First off, hats off to Jurgen, I saw his post but initially let it slide
because I thought I'd answered someone else earlier about how the timing
issues had been solved for 3.1. But it looks like maybe that message
wasn't seen by everyone and for sure, it needs a bit more explaining. So
let me see if I can unvail some of the mysteries surrounding
PFCLOCKPERIOD ...
> Jurgen,
>
> I don't have an answer for you, but I just had to say that this was one
> of the most meticulously documented requests for information that I have
> ever seen.
I agree; I wish my girlfeind would explain issues to me in this much
detail too :)
> I hope that it is not ignored. CPU's will only get faster, and this
> irratating problem needs explained.
It has been addressed and is in 3.1 which is currently in Alpha but should
go to beta in a week or so from now at which point many more people out
there with faster systems can take a whack at it at see if it actually
does fix the problem.
> -----Original Message-----
> From: owner-info-performer++at++performer.engr.sgi.com
> [mailto:owner-info-performer++at++performer.engr.sgi.com]On Behalf Of
> jurgen.rusch++at++philips.com
> Sent: Tuesday, October 21, 2003 11:05 AM
> To: info-performer++at++sgi.com
> Subject: [info-performer] Re: Re: no statistics (= the use of
> PFCLOCKPERIOD)
>
>
> Dear all,
>
> those of us that have a fast CPU need to set PFCLOCKPERIOD,
> at least on MS-Windows systems.
> Searching for PFCLOCKPERIOD in the mailings (and from personal
> e-mails) the advice was (and still is) to set that environment
> variable to 2300000000000000.
First off, let me explain how we've setup things in our tree. The goal is
to obtain the processor's speed. On IRIX we use syssgi() with the
SGI_QUERY_CYCLECNTR token. On Linux we inspect the file /proc/cpuinfo and
find the processor's speed by parsing the string which contains "cpu MHz"
in it. And on windows ... we use QueryPerformanceFrequency().
Sadly, as Jurgen noted, we _WERE_ using a 4 byte integer (32 bit) to store
this value on windows (on IRIX & Linux this functionality is stored in a
separate file and hence we didn't have this problem). Not good. With 3.1
we use a 64 bit integer to store the value.
Just for fun, I also experimented with different methods for determining
the clock's period such as examining the values in the registry regarding
procesor speed and got almost the same value as what
QueryPerformanceFrequency(). In the case of my crufty old PC which runs at
936 MHz, Windows has determined that it's actually running at 936.77 MHz.
But that's getting a bit off topic ...
Anyhoo ... we take the value computed here and divide 1.0 by it and then
use that to set the tick2Sec variable of our Clock and this is why we need
it, because we use this variable to then compute the actual elapsed time.
The (greatly simplified) pseudo-code for this hence looks something like:
double pfGetTime() {
return initialTime + returnValueFromQueryPerformanceCounter() * tick2Sec;
}
and tick2Sec is 1.0/clockPeriod. tick2Sec is cached, period isn't.
I hope this explains things sufficiently ...
For historical reasons this variable was inserted because the processor's
speed we queried on some IMPACT systems didn't match up very well and
hence we introduced this variable as a way to set the proper value. It
stuck ...
> Experiments with PFCLOCKPERIOD
> ------------------------------
> Since we have to wait till Performer 3.1 (see e.g. Guillaume Millets
> maling dated 10/09/2003, 01:18:46 titled "Re : Re: [info-performer]
> No statistics") I thought it was a good idea to experiment with
> the value of PFCLOCKPERIOD. For each value of PFCLOCKPERIOD I
> ran RUN_TOWN.BAT (on Windows-XP on a dual Pentium 2.4 GHz Xeon
> with 1GB RAM and an ATI FireGL X1 128 MB) and sent STDOUT (with
> >) and STDERR (with 2>&1, yes, this also works on Windows-XP!)
> to a different LOG file.
> For each run of Performer Town I noted the APP/CULL/DRAW times
> as observed in the timing statistics and noted whether I could
> use the mouse for driving/flying or not.
> The results are shown in the table below (the numbers in the first
> two columns are represented using a , before each three zeroes for
> legibility only):
>
> PFCLOCKPERIOD picoseconds APP/CULL/DRAW in ms.
> (set in RUN_TOWN.BAT) (reported in LOG) (from 'stats'-panel)
> 2,300,000,000,000,000 2,063,319,040 0.2/0.0/7.3
> 2,000,000,000,000,000 1,233,977,344 0.4/0.1/13.3
> 1,000,000,000,000,000 -1,530,494,976 0.0/0.0/0.0
> 100,000,000,000,000 276,447,232 1.7/0.3/60.0
> 10,000,000,000,000 1,316,134,912 0.3/0.1/13.0
> 1,000,000,000,000 -727,379,968 0.0/0.0/0.0
> 100,000,000,000 1,215,752,192 0.4/0.1/12.9
> 10,000,000,000 1,410,065,408 0.3/0.1/12.6
> 1,000,000,000 1,000,000,000 0.4/0.1/18.1
> 100,000,000 100,000,000 4.2/0.8/160
> 10,000,000 10,000,000 34/8.5/1800
> 1,000,000 1,000,000 1200/85 /16000
> 100,000 100,000 90000/750/230000
>
> [column 3 was obtained by positioning the viewpoint just below the
> clouds, south of the town, looking at the town (i.e., in northward
> direction) and have the town and surrounding ranches in view. Thus
> there were as much objects in the field-of-view as possible and
> the DRAW time was as high as possible.]
>
> In the cases that column 2 (picoseconds reported in LOG-file) was
> negative the APP/CULL/DRAW times were all zero and the mouse could
> NOT be used to fly or drive or whatever movement.
>
> Please observe that the APP/CULL/DRAW timings are inversely
> proportional to the number in column 2 (for positive values
> in column 2).
>
>
> A simple C-program
> ------------------
> I was struck by the strange behaviour of column 2. How was it
> derived from the value of PFCLOCKPERIOD? Well, quite easy:
> I wrote a very short C program with this body:
>
> int i;
> int ret;
> while (EOF!=(ret=scanf("%d",&i))) {
> if (ret==1) { printf("%d\n",i); };
> }
>
> and fed this program with the values of column 1, i.e., with
> the values that I had used for PFCLOCKPERIOD (without the ,).
> And you know what? The output was EXACTLY column 2 !!
>
> Conclusion
> ----------
>
> +---------------------------------------------------+
> | OpenGL Performer reads the value of PFCLOCKPERIOD |
> | into a signed integer of length 4 bytes. |
> +---------------------------------------------------+
>
> A consequence of this is that setting PFCLOCKPERIOD to a value
> N will result in the same behaviour of OpenGL Performer as
> when setting PFCLOCKPERIOD to a value of mod(N,K) with K=2^32
> (or N%K in C-language).
>
> Final verification
> ------------------
> As a final verification I ran Performer Town with PFCLOCKPERIOD
> set to 2^31-1=2,147,483,647 (the highest positive integer that
> can be represented by a signed 4 byte integer) and found that
> very same number in the LOG-file (the value for column 2).
>
> I then set PFCLOCKPERIOD to 2^31=2,147,483,648 (which maps to
> the lowest negative integer that can be represented by a signed
> 4 byte integer, namely -2,147,483,648) and indeed found that
> negative number in the LOG-file. Furthermore, the mouse could
> NOT be used to control flying/driving.
>
> My questions to SGI
> -------------------
> In older mailings I read that PFCLOCKPERIOD should be set to the
> number of picoseconds per clock-cycle. Remembering that one
> picosecond is 1E-12 seconds the number of picoseconds per
> cycle for a 2.3 GHz system is (1/2.3E9)/(1E-12)= 1E12/2.3E9 =
> 1000/2.3 = (approx) 400.
> What I found out was that for PFCLOCKPERIOD of 10,000,000 or
> lower the timings were non-realistic and properly flying or
> driving in Performer Town was impossible. So, to what value
> should I set PFCLOCKPERIOD?
The value of PFCLOCKPERIOD is converted to an int via atoi() (which should
probably be changed to use atol()).
(1 << 31) -1 == 2147483647; this is the biggest value you can currently
assign to PFCLOCKPERIOD that will make any sense (as you noted above). If
you go for larger than this, the higher bits will be ignored. Off the top
of my head I can't think of anything else to do... (it would have been
sufficient to have stored period as an unsigned int but alas, it wasn't.)
You may want to give a stab at having a clock period which is set to half
(or by a factor of ten so that you can just move the decimal point by one
in your head when you look at stats) of what your system is actually
running at but who knows what else that will mess up. Either way,
2147483647 is the highest value that you can set it to. For a 2.3 GHz
processor this will give you a 7% error. Not good ... but until 3.1
there's not much else we can do.
> Hence:
>
> QUESTION 1: What does PFCLOCKPERIOD exactly represent?
See above.
>
> Furthermore:
>
> QUESTION 2: Could SGI document the environment variable
> PFCLOCKPERIOD?
It looks like it _WAS_ documented in chapter 4 of the performer_eoe
relnotes "way-back-when" (Performer 2.0) but sadly this part of the
relnotes never made it into future versions. Normally we document all
environment variables of this type in the "Performer" man page (man
Performer) but this wasn't isn't there. I've created a new bug for this (#
903027).
> As to the latter question: I looked in SGI document 007-1680-080,
> the "OpenGL Performer Programmer's Guide" which documents release
> 3.0 and did not find PFCLOCKPERIOD as a string in it.
See above. Our bad. Sorry.
>
> With kind regards, Jurgen Rusch
Thank you very much for the detailed reply!
Before 3.1 arrives there isn't a whole lot you can do ... I can think of a
way to hack into the library and modify the value which gets computed by
having set the clock period but due to all the DLLEXPORT cruft, I'm not
100% convinced this would work. I think probably the easiest thing to do
is simply to use 3.1 -- it is just around the corner after all :)
I sincerely hope this answers all of your questions; please let me know if
there's anything else.
A+,
Alex.
This archive was generated by hypermail 2b29 : Thu Oct 23 2003 - 11:50:10 PDT