TimeDX Help.


Time Video Mode

    The primary purpose of this test is to tune the Vertical Retrace Thread.   This thread is responsible for detecting the retraces of the display and determining if a retrace was missed.   If a retrace is missed it is not particularly big deal (it in fact happens a lot of the time) as DMDX only needs to know that any given retrace is due to occur sometime after the most recent one, so it can time them out with ease.   The problem the retrace thread faces is that other processes can be active (the primary culprit is usually a DirectDraw blit, a block transfer to the video memory, for this reason blits are usually broken up into multiple smaller chunks) and cause it to miss an entire retrace, even if it runs at the highest priority.
    In detail then, what the retrace thread does is this: Assuming the previous retrace was correctly handled it goes to sleep for some period to allow the rest of the machine's threads some execution time (including of course DMDX's other threads too).   It then wakes up and starts to poll for the retrace until it either detects it or it determines that the retrace has been missed.   Whatever processing needs to be done by the display routines is done and then it repeats the process by going to sleep again.   The time that it requests to go to sleep for is scaled down if it missed the previous retrace in proportion to how long it missed it by.   The time that it actually goes to sleep for is quite often longer than it requested because the thread that was executing while it was asleep can start a process (like a blit) that cannot be stopped until it finishes (hence the reason for breaking up blits).
    Prior to me adding the high performance timer code in TimeDX 1 the values for sleeping and so on were quite difficult to determine automatically, however since it's addition almost no user tweaking is needed beyond making sure that the
Refresh Rate test is functioning properly.
 


    This test is the same as the Video and Millisecond Timer test except that it now starts another thread that synchronizes itself with the Vertical Retrace and when one occurs it saves the time that it occurred.  Additionally it can play the Sound Buffers setup in the Sound section to determine the effect playing speech has (if any) on the synchronization routines.

    Initially it switches to the last selected
Video Mode and times the refresh rate using the Refresh Rate test to obtain four values necessary for the correct operation of the Vertical Retrace thread (three if using the Direct3D rendering path as 'blitting' is handled differently so the 'blit' fields are all disabled).  If you suspect the values are in error due to an error message or visual anomalies you can re-determine them with the "Re-Determine Automatic Values" button.  Due the fact that no program is perfect they are offered for user tuning, these tuned values will be written to the registry and DMDX will pick them up and use them when it is run later (unless it's running in Auto Mode of course). The values are:

    Using the high performance timer TImeDX (or DMDX) can know when the previous retrace occurred to within a few microseconds, knowing the duration of a refresh interval to the same accuracy it can therefore predict the time that a retrace should have occurred at with very little error and can therefore survive the absence of an actual retrace detection for a large number of retrace intervals -- assuming nothing hogs the CPU cycles for more milliseconds than there are in a retrace, and even then it can get back on track without actually detecting a retrace as it will take many missed retraces before the cumulative error rises to a point where an actual retrace has to be detected.
   

    The "Automatic" values are the values that my code has come up with based on the results of the Refresh Rate test, they should usable conservative values, the sleep time can usually be increased on good systems.   The "Registry" values are the values that DMDX and any other routine synchronized with the retrace will use.


Important:
    Once you have tuned the values nicely clicking the "Save values in Registry" button will record them for posterity -- for this video mode, a critical thing to remember is that there are a set of these values for every video mode.   DMDX will not run until you have done this for each video mode you intend to use unless you use Auto Mode (in which case you don't ever need to use this test).

    The "Use Millisecond Too" check box turns on code that records millisecond callback latencies, detailed in the
Millisecond Timer test.
    The times provided for the sound buffers (see
Sound for buffer properties) are the retrace count at which to commence playing that buffer.   If it is zero the buffer is not played, if all buffers are zero then the primary sound buffer is not setup (meaning there is no overhead for sound).   You can use the retrace dump to see if the commencement of a buffer's playing corresponds to an unsightly increase in loss of synchronization or increase in lost time.   The recycle time enables the buffers to be played repeatedly, if a given buffer has not finished playing by the time it is recycled it will continue to play out and not be restarted again that cycle (ie, if it has finished by the next cycle it will then play every second cycle).

    After the test has run the details of the last couple of seconds of retraces are displayed in the list box and the percentage of those retraces that were timed out, the percentage of retraces that were timed out after an another timed out retrace and the percentage of certain errors.   The Timed out retraces are not necessarily bad, we only have to know some time during that retrace that it occurred -- a new display screen is not 'flipped' until the next retrace occurs and this is done in hardware, all the code has to do is set up the flip before the next retrace occurs (same goes for Direct3D, only the screens are 'presented' instead of 'flipped').   The Multiple misses are worse, but they are still of little concern because two in a row still has a very strong chance of being OK.   Certain errors are bad however, these occur when the retrace thread wakes up and the time spent sleeping is longer than the duration of that retrace or when 90 timed out frames occur in a row.  When DMDX is running and a critical error occurs when a frame had to be flipped (or presented) then a display error would result (if OTOH nothing had to happen on that retrace nothing is lost).



    The info on a given retrace is the
millisecond time that the retrace thread started looking for that retrace, the retrace number (or video time as DMDX refers to it), the time spent sleeping for that retrace (the number in brackets is the time requested to sleep for), then the time the retrace was found at or was timed out at and assumed to have been missed (the time since we started looking for the retrace, not the time since it stopped sleeping).   After that comes the millisecond time that the retrace occurred at, if the retrace was actually found then the millisecond it occurred at is presented here (and it's value will be repeated as the time that the retrace thread started looking for the next retrace), if it was timed out then the calculated time it occurred at is presented instead.   Next is the time lost in the retrace thread when checking the vertical retrace status, most likely lost to because a 'blit' was in progress but other processes can interfere as well.   If the retrace was a Multiply missed retrace (i.e. two or more on a row have been missed) then three asterisks are added, if six hash marks follow the retrace it is a certain error.
    The sleeping time is the time that the code is not looking for a retrace but allowing the rest of the machine to do it's thing (like 'blitting' and preparing the next frame etc.), following a timed out retrace less time is spent sleeping (down to no time at all if was missed really badly).
    Occasionally you will see a timeout longer than the timeout specified, this occurs for one of two reasons, either some other process preempted the retrace thread or a 'blit' was in progress and for the duration of the blit we were not able to get at the vertical retrace status, the 'blit' essentially preempted the vertical retrace thread (see below, tuning the maximum lines to 'blit').

    There are two mechanisms to tune the retrace interval, one good and the other very good.   The first good mechanism is to basically rely on the automatic routine. Use the "Re-Determine Automatic Values" button a few times, if they consistently return the same value you can be pretty sure that they are right.   As an iterative process you can see what value the test itself comes up after a while once the retrace value stops changing and then enter that back in.   The second method involves machined using the original DirectDraw renderer and not the new Direct3D one. Assuming you're using DirectDraw you can use the enhanced retrace interval test by clicking the "Enh. Retrace" button, if your setup doesn't stand a chance of the test executing it will tell you as DirectX 7 informs TimeDX that the video card can't do it.   There is a chance that even then the test won't work as one of my machines just demonstrated to me, it had DirectX 7 but not recent video drivers (or screwed up video drivers), updating the drivers fixed the problem, now DirectX tells me the test won't work...   Basically the enhanced test uses a feature of DirectX 7 that allows TimeDX to flip the video buffers regardless of the state of the retrace.   The test swaps between two buffers, one buffer with a blue background and the other with red background (the text contains the current retrace rate), and it swaps between these buffers at twice the retrace interval so if the test is functioning (ie. the drivers are capable of flipping without a retrace) half the screen will be blue and the other half red -- with the exception of a few flickers as TimeDX gets preempted by other processes.   If the buffers are swapped at what is indeed twice the retrace interval then the red and blue portions will remain fixed on the screen, they won't travel up or down, if the buffers are swapped at a slightly faster rate than the retrace interval the bands of color will scroll up the screen, if at a slower a rate, down the screen.   The + and - keys (as well as the = and _ keys) add or subtract one microsecond to the retrace interval so it can be dialed in exactly.   If the hardware doesn't support the unsynched flip then one of two things appears to happen, you either get a purplish screen (that might flicker a little if the refresh interval is 60Hz) because the flips are happening in synch with the retrace (as traditional flips would) or you just get a red screen because the flip is doing nothing.

    When tuning the sleeping time look for retraces where the maximum time was spent sleeping, if a retrace is repeatedly timed out after this then the sleeping time needs to be lowered, it is missing retraces while asleep.   You don't want to arbitrarily lower this value too much however as the rest of the machine will be starved of CPU cycles and the maximum maintainable frame rate will drop as there will be less time to 'blit' the next frame to the display card.   As a general rule this value should be the
Retrace Interval minus the longest lost time, maybe a millisecond higher.   This is because the video retrace can go to sleep for it's sleep time and just before it is due to wake up a 'blit' is started (assuming it is the 'blit' causing the lost time) causing it to loose the 'blit' time as well as it's sleep time, if these sum to larger than the retrace interval the retrace thread is going to miss the retrace.   If your lost times are always less than three milliseconds make the sleep time at least three milliseconds less than the retrace interval anyway.   Another thing to note is the reported sleep times and the requested sleep time (in brackets), if they are close to each other (ie the machine is not sleeping for multiple milliseconds longer than requested) the sleep time could be increased substantially freeing up more time for other threads to execute (more relevant if you will be displaying video clips or playing sound files).   Machines that have low millisecond callback standard deviations also usually have highly correlated sleep times.

    When tuning the timeout value you want to look at the retrace following a timed out retrace.   Assuming the retrace was caught correctly (i.e. you don't have two timed out retraces in a row) and the number of milliseconds that it was found after is two or lower the timeout value is dangerously large, the previous retrace waited almost until the next retrace occurred before it was decided that the previous had been missed -- the timeout value needs to be lowered (assuming the reported timed out time was not more than a millisecond larger than the specified timeout value, if this is the case see tuning the maximum lines to Blit below).   If the retraces are being timed out and the next retrace waits the timeout value as well then the timeout value is too small, the retraces are being given up for lost before they have actually occurred -- the usual hallmark of a timeout value set too low is a long string of missed retraces.   Additionally if you have used the
Refresh Rate test and know the video mode's refresh rate as the vertical retrace thread is being tested watching the msecs/retrace will give you an idea if the timeout value is too short as a reported msecs/retrace that is low can indicate that the retrace thread is timing the retraces out too early.   As a general rule the timeout value should be the refresh rate plus three hundred microseconds (the default value).

    Direct3D users can skip the following maximum lines to 'blit' discussion.  When tuning the maximum lines to 'blit' examine the timed out retraces that are longer than the timeout value, if the sum of the time spent sleeping and the
lost time is equal to the reported timed out time a Blit is more than likely to be the culprit, if the lost time is zero then something else is responsible (which I haven't seen yet and can therefore not help you with).   To lower the lost time and hence eliminate the timeouts longer than the specified limit decrease the maximum lines to Blit.   Unfortunately this also lowers the speed at which blits can be performed, you can get some idea by using the alternate display (see 'A" below) where you can see how long blits are taking, I usually like to have an average blit being 1/3 of the retrace interval.   After you have lowered the maximum lines to Blit you can probably go back and increase the sleeping time.   If the lost time is always zero (as may be the case if your video card has a hardware blitter) you can raise the maximum lines to Blit all the way up to the entire screen.   In general I have found that if I tune the size of Blits to give lost times no larger than 4 milliseconds the retrace thread still works well, however this is with sleep times 4 to 5 milliseconds lower than the actual refresh.
    Basically what you want is sleep_time + longest_blit_time < retrace_interval and the largest lost time typically will be the longest_blit_time.

    With the high performance timer it is a bit superfluous to have the timeout specified separately from the refresh interval I admit (usually it would be expressed as the time beyond the retrace duration), however I hate to chuck out a bunch of code that works quite well.   The refresh interval should not need any user tuning as the code that determines the automatic values for it are quite robust.   Perhaps if after running the retrace thread with no significant loss of synch and having had the retrace interval reported there not change for some time and you notice that the values differ you could change the interval to match.

    The 'A' key is used here to provide an alternate display (the Video and Millisecond timer display actually) of the 'blitting' times, this is to provide an index on how much of a performance hit we are taking by running two threads -- these 'blitting' times will go up as you decrease the sleeping time of the retrace thread.
    The 'R' key resets all values.   All values are automatically reset after the first few trials to ignore bad startup conditions that tend to prevail on all machines, see the
Refresh Rate test.





TimeDX Index.