From: David S. <dsc...@vi...> - 2002-06-21 19:46:15
|
First of all, keep in mind that there are two rates involved: - How many times per second VPython's background rendering thread can draw the scene with OpenGL. (the "frame rate") - How many times per second your while loop executes ("loop rate" or "update rate") These two numbers can be entirely different. Your program measures the second, which is also what rate() controls. There is no way to change the rendering frame rate in VPython (except to buy a faster computer :), and VPython keeps rendering the screen even when there is no mouse input and no updates by the program. Now, what rate() does is fairly simple. It could be written in Python something like this (with some error checking and so on omitted): origin = time.time() def rate(N): global origin delay = 1.0 / N float t = delay - (time.time() - origin) if t > 0.010: time.sleep(t) else: while (delay - (time.time() - origin) > 0): pass origin = time.time() Essentially, it just sleeps or wastes CPU time until the previous iteration of the loop took at least 1/N seconds. The reason this can still have an effect when your "loop rate" is less than N, because your loop will not execute in exactly the same wall clock time each time, and rate() does not attempt to average across iterations. For example, let's say N = 50, and your loop (without the call to rate()) takes 10ms for every even iteration and 30ms for every odd iteration. On each even iteration, rate() will sleep for 10ms, so that that iteration takes 20ms. On odd iterations it will not sleep at all. The net effect is that the frame rate changes from 50 (20ms average) to 40 (25ms average). Another factor is that the operating system's Sleep() function is extremely inaccurate. The time slices used by Windows are often on the order of 15ms, which is quite a large margin of error in the type of test you are doing. This likely accounts for the "stairstepping" effect you are seeing, and it might also account for some of the variation. The reason the function above uses an inefficient spin loop for sleeps less than 10ms is that for such lengths of time, the average time taken by a Sleep can be a large factor different than the number passed to it. Hope that helps. I haven't actually done any experiments to confirm these hypotheses, so take them with a grain of salt. Dave > -----Original Message----- > From: vis...@li... > [mailto:vis...@li...] On > Behalf Of Gary Strangman > Sent: Friday, June 21, 2002 1:58 PM > To: Bruce Sherwood > Cc: vis...@li... > Subject: Re: [Visualpython-users] rate() function > > > > For what it's worth, this _only_ happens when the computer > can't keep up (like, when drawing 500 background objects). > When the computer is able to keep up, a rate(n) gives an > actual framerate of n (or very slightly less, thanks to > random background processes. > > > Many thanks for offering this analysis tool. It sure looks like > > something > > is very wrong with the rate machinery. A quick look at the > Visual code > > indicates that rate ought to work fine, but it most > assuredly isn't working > > fine, as you show conclusively. > > > > Bruce Sherwood > > > > At 11:35 AM 02/06/21 -0400, Gary Strangman wrote: > > > > >Hi all, > > > > > >This might be a bit off-topic--perhaps hardware > related(?)--but does > > >anyone know exactly what happens when you pick value of N > such that > > >your computer can't handle a given "rate(N)" visualpython > statement? > > >Do frames get dropped? Or is it dependent on one's > graphics card, or > > >screen refresh rates, or openGL implementation? Using the program > > >below, my _actual_ framerate increases as a stair-stepped > function of > > >the _specified_ framerate. What I find odd is that the _actual_ > > >framerate does keep on increasing. That is, rate(50) > doesn't give me > > >a 50Hz frame rate, but (according to my loop anyway) using > rate(100) > > >gives me a better than 50Hz frame rate. I would think that > the actual > > >framerate should increase linearly to the point where > one's computer > > >is maxed out, and then plateau indefinitely. Apparently > that's naive. > > >Any ideas? I've tested this on both a couple machines (though both > > >are portables with, of course, LCD monitors). > > > > > >Thanks in advance for any guesses (or better yet, answers) ... > > > > > >Gary > > >strang-@at@-nmr.mgh.harvard.edu > > > > > >--- cut here --- > > > > > >from visual import * > > >import time, sys, whrandom > > > > > >scene.title = "Speed test" > > ># Create 2 frames > > >fworld = frame(pos=(0,0,0)) > > >ftarget = frame(frame=fworld,pos=(0,0,0)) > > >ftarget.pos = (0,0,0) > > >fworld.pos = (0,0,10) > > > > > ># Draw some main objects > > >body = cylinder(frame=ftarget, pos=(0,0,0), axis=(0,0,0.35), > > >radius=1, > > >color=(0,0,1),visible=1) > > >pin = cylinder(frame=ftarget, pos=(0,1,0), axis=(0,1,0), radius=1, > > >color=(1,1,1),visible=1) > > >pinball = sphere(frame=ftarget, pos=(0,-1,0), radius=1, > > >color=(1,1,0),visible=1) > > >topbox = box(frame=ftarget, pos=(0,0.34,0.20), axis=(0,1,0), > > >length=0.2,width=0.1,height=0.1, color=(1,0,0),visible=1) > > >horizon = cylinder(frame=ftarget, pos=(-5,2,0), > axis=(10,0,0), radius=1, > > >color=(0,1,0),visible=1) > > > > > >xINC = 0 > > >yINC = 0.001 > > >zINC = 0.003 > > >rollINC = 0 > > >pitchINC = 0 > > >yawINC = 0 > > >scene.autoscale = 0 > > >NUM_DOTS = 500 > > >RADIUS = 120 > > >rad = 0.4 > > ># now draw background objects > > >for i in range(0, NUM_DOTS): > > > x = whrandom.random() - 0.5 > > > y = whrandom.random() - 0.5 > > > z = whrandom.random() - 0.5 > > > length = math.sqrt(x*x + y*y + z*z) > > > x = x / length * RADIUS > > > y = y / length * RADIUS + 1.8 > > > z = z / length * RADIUS > > > sphere(pos=(x,y,z),radius=rad) > > > > > >frameratelist = [] > > >for framerate in range(10,250,1): > > > framecount = 0 > > > starttime = time.clock() > > > while framecount<5*framerate: # integrate over, > theoretically, 5sec > > > rate(framerate) > > > framecount += 1 > > > fworld.pos.x -= xINC > > > fworld.pos.y -= yINC > > > fworld.pos.z = framecount*zINC > > > > > > # Rotate "CAMERA" (actually, move whole _world_ > around camera) > > > fworld.rotate(angle=pitchINC, axis=(1,0,0), > > > origin=scene.mouse.camera) > > > fworld.rotate(angle=yawINC, axis=(0,1,0), > origin=scene.mouse.camera) > > > fworld.rotate(angle=rollINC, axis=(0,0,1), > origin=scene.mouse.camera) > > > endtime = time.clock() > > > print "Rate(%i): %i frames in %2.2f sec = %2.2f frames/sec" % > > > (framerate, framecount, (endtime-starttime), > framecount/(endtime-starttime)) > > > frameratelist.append((framerate, framecount, > (endtime-starttime), > > > framecount/(endtime-starttime))) > > > > > > > > > > > >------------------------------------------------------- > > >Sponsored by: > > >ThinkGeek at http://www.ThinkGeek.com/ > > >_______________________________________________ > > >Visualpython-users mailing list > > >Vis...@li... > > >https://lists.sourceforge.net/lists/listinfo/visualpython-users > > > > > > > > > > ------------------------------------------------------- > Sponsored by: > ThinkGeek at http://www.ThinkGeek.com/ > _______________________________________________ > Visualpython-users mailing list > Vis...@li... > https://lists.sourceforge.net/lists/listinfo/visualpython-users > |
From: Bruce S. <bas...@un...> - 2002-06-22 15:20:41
|
The crux of the matter seems to be the question, what is the accuracy of the Windows clock? On the Windows machine where I tried Gary's test routine and saw the bizarre results he reported, I got 700 loop/sec with no rate statement, which implies that one loop took 1.4 millisecond. If the clock is accurate to microseconds, no problem. If the clock is accurate to 15 ms (1/60 s?), it's hopeless. Bruce Sherwood At 03:45 PM 6/21/02 -0400, you wrote: >The time slices used by Windows are often on the >order of 15ms, which is quite a large margin of error in the type of >test you are doing. At 04:48 PM 6/21/02 -0400, Gary Strangman wrote: >Interestingly, replacing the rate() call in my previous program with a >spin-loop of the short you mentioned above (but based on time.clock(), >which on Windows is supposed to be accurate down to microseconds), I still >get the stair-stepping ... |
From: Arthur S. <aj...@ix...> - 2002-06-22 20:49:58
|
I am refactoring some code, focusing on performance issues. And find it quite common in my code to be calculating the squared length of a vector. A look at cvisual finds mag2() already there as the underlying function for mag(), but it is not exposed to Python. So in doing mag(vector)**2 I am essentially calculating a square root(in C) and then squaring it (in Python). Unpretty. I did the trivial work to expose mag2 as a Python function, and am using it, and hoping the change could be made in the "official" distribution Art |
From: Arthur S. <aj...@ix...> - 2002-06-25 00:17:21
|
Bruce writes - > Sounds like a useful idea. I'll put this on a to-do list. >Thanks! And thanks for the response. I do think that mag2 would be useful - a clue in fact being its utilization in the cvisual code. I can send along a small "patch" which exposes it to Python. Truth is I am first learning about extending Python via C++ by digging a bit into the cvisual code. And am already doing other customizations. I would not like to have my (small) user base need to rely on my own "forked" cvisual - especially since my changes are likely to be minor and only add stuff, rather than change any existing functionality. I am therefore hoping that VPython can begin to come more of a collaborative Open Source project. That is someone like myself proposing a change *and* submitting a patch - with its acceptance opened up to discussion both as to the soundness of the feature *and* its implementation. What you do think? Art |
From: Bruce S. <bas...@un...> - 2002-06-25 01:54:29
|
Absolutely! It was always the intention and hope that users would jump in with suggested improvements. So do please post your patch. Thanks. Bruce Sherwood At 11:08 AM 02/06/24 -0400, Arthur Siegel wrote: >Bruce writes - > > > Sounds like a useful idea. I'll put this on a to-do list. >Thanks! > >And thanks for the response. I do think that mag2 would be useful - a clue >in fact being its utilization in the cvisual code. I can send along a small >"patch" which exposes it to Python. > >Truth is I am first learning about extending Python via C++ by digging a bit >into the cvisual code. And am already doing other customizations. > >I would not like to have my (small) user base need to rely on my own >"forked" cvisual - especially since my changes are likely to be minor and >only add stuff, rather than change any existing functionality. > >I am therefore hoping that VPython can begin to come more of a collaborative >Open Source project. > >That is someone like myself proposing a change *and* submitting a patch - >with its acceptance opened up to discussion both as to the soundness of the >feature *and* its implementation. > >What you do think? > >Art |
From: Gary S. <st...@nm...> - 2002-06-21 20:49:55
|
> These two numbers can be entirely different. Your program measures the > second, which is also what rate() controls. There is no way to change > the rendering frame rate in VPython (except to buy a faster computer :), Question: if you've re-computed a (or requested a new) frame before the previous one was done rendering, does the rendering re-start with the new frame? I presume they don't pile up in a buffer somewhere ... > Now, what rate() does is fairly simple. It could be written in Python (snip) > while (delay - (time.time() - origin) > 0): > pass > origin = time.time() (snip) > > The reason this can still have an effect when your "loop rate" is less > than N, because your loop will not execute in exactly the same wall > clock time each time, and rate() does not attempt to average across > iterations. > > For example, let's say N = 50, and your loop (without the call to > rate()) takes 10ms for every even iteration and 30ms for every odd > iteration. On each even iteration, rate() will sleep for 10ms, so that > that iteration takes 20ms. On odd iterations it will not sleep at all. > The net effect is that the frame rate changes from 50 (20ms average) to > 40 (25ms average). Interestingly, replacing the rate() call in my previous program with a spin-loop of the short you mentioned above (but based on time.clock(), which on Windows is supposed to be accurate down to microseconds), I still get the stair-stepping ... which I don't understand. I believe the above explanation will, at most, provide only a single plateau. Or perhaps I misunderstood something ... Gary strang-@at@-nmr.mgh.harvard.edu |
From: Bruce S. <bas...@un...> - 2002-06-22 17:37:15
|
Oops. I see I misread Dave Scherer's comment: 15 ms time slices have nothing to do with clock accuracy. The clock could be accurate to a microsecond yet with time slices allocated by Windows to processes with 15 ms slop the clock accuracy is irrelevant. Bruce Sherwood At 11:22 AM 6/22/02 -0400, Bruce Sherwood wrote: >The crux of the matter seems to be the question, what is the accuracy of >the Windows clock? On the Windows machine where I tried Gary's test >routine and saw the bizarre results he reported, I got 700 loop/sec with >no rate statement, which implies that one loop took 1.4 millisecond. If >the clock is accurate to microseconds, no problem. If the clock is >accurate to 15 ms (1/60 s?), it's hopeless. > >Bruce Sherwood > >At 03:45 PM 6/21/02 -0400, David Scherer wrote: >>The time slices used by Windows are often on the >>order of 15ms, which is quite a large margin of error in the type of >>test you are doing. > > >At 04:48 PM 6/21/02 -0400, Gary Strangman wrote: >>Interestingly, replacing the rate() call in my previous program with a >>spin-loop of the short you mentioned above (but based on time.clock(), >>which on Windows is supposed to be accurate down to microseconds), I still >>get the stair-stepping ... > > > > >------------------------------------------------------- >Sponsored by: >ThinkGeek at http://www.ThinkGeek.com/ >_______________________________________________ >Visualpython-users mailing list >Vis...@li... >https://lists.sourceforge.net/lists/listinfo/visualpython-users |
From: Bruce S. <bas...@un...> - 2002-06-23 19:02:46
|
Sounds like a useful idea. I'll put this on a to-do list. Thanks! Bruce Sherwood At 05:00 PM 02/06/22 -0400, Arthur Siegel wrote: >I am refactoring some code, focusing on performance >issues. > >And find it quite common in my code to be calculating the squared >length of a vector. > >A look at cvisual finds mag2() already there as the underlying function >for mag(), but it is not exposed to Python. > >So in doing mag(vector)**2 I am essentially calculating a >square root(in C) and then squaring it (in Python). Unpretty. > >I did the trivial work to expose mag2 as a Python function, and >am using it, and hoping the change could be made in the "official" >distribution > >Art > > > >------------------------------------------------------- >Sponsored by: >ThinkGeek at http://www.ThinkGeek.com/ >_______________________________________________ >Visualpython-users mailing list >Vis...@li... >https://lists.sourceforge.net/lists/listinfo/visualpython-users |