TimeDX Help.


Task Priorities
   
    The priorities of various DMDX tasks can be set. By default these tasks will run at normal priority levels and are preemtable by other higher priority tasks, raising their priority therefore decreases the probability that a display will be presented incorrectly -- the trouble with this is that DMDX may suddenly stop some system critical task from being performed correctly. So the user is presented with the ability to turn these on should they be experiencing display errors.



    The first option is not so much a priority but a simple flushing of all DMDX files at the beginning of each item so that Win32's write behind caching doesn't write the buffers out to disk half way through a display sequence. Why not do this always? Well, it raises the average ISI for a start and there is always disk activity before any trial.  Note that prior to version 4.0.3.0 of DMDX item files that have large numbers of <SkipDisplay> items in them will be adversely affected by turning Always Flush File Buffers on as it is only on later versions that skip display items no longer flush the file buffers (if it's turned on here).  To elaborate, in the old days background disk activity during an item was enough to cause millisecond callback variations if not outright display errors and if Windows was allowed to queue disk requests arbitrarily disk activity could (conceivably) occur during critical times of an item's presentation.  Machines are fast enough now and there's so much else going on anyway that forcing DMDX to flush it's file buffers is moot, if not outright counter productive.

    The second option is to make DMDX not overwrite diagnostics.txt each time it runs. If enabled someone will either have to periodically prune or outright delete the diagnostics.txt file as it will grow to enormous sizes over time.

    The third option is to boost the vertical retrace thread's priority to THREAD_PRIORITY_TIME_CRITICAL if the use of the high performance timer is enabled, if the high performance timer is disabled it's priority can't be boosted, the millisecond timer will be preempted by the retrace thread. This will also interact with the fourth option below, changing the priority of the sound thread.

    The fourth option is to boost DMDX's process priority to either HIGH_PRIORITY_CLASS or REALTIME_PRIORITY_CLASS.

    The fifth option of modifying the sound thread's priority is provided to minimize the variability of the latency of sounds. Most machines have a latency of around 15 milliseconds, however with the retrace thread (usually running at ABOVE NORMAL) preempting the sound thread there appears to be an additional variable latency, perhaps as much as 20 milliseconds. Assuming you have the equipment to measure this some compromise may be reached to minimize this variability.


    Currently the main loop of DMDX that moves video memory into back buffers and file I/O runs at NORMAL priority, the vertical retrace and sound threads run at ABOVE NORMAL, the input related threads run at HIGHEST and millisecond scheduler runs at TIME CRITICAL (I'm guessing, the callback's priority is set by the operating system, certainly it isn't preemted by much). Note that the input devices DigitalVOX and RecordVocal run at the HIGHEST priority even though they are sound related.

    The priority a thread has (ie: whether it or some other machine process gets executed) is determined by a combination of the process's priority (DMDX's priority) and the thread's priority. The whole issue of how these priorities interact is enormously complicated, for example from the win32 help:
   

Be very careful when manipulating priorities to ensure that a high-priority thread does not consume all of the available CPU time. A thread with a base priority level above 11 interferes with the normal operation of the operating system.

The following table shows the base priority levels for each combination of priority class and thread priority value. Note that for IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, and HIGH_PRIORITY_CLASS, this base level can receive dynamic boosts.

BasePriority class/thread priority
1Idle, normal, or high class, THREAD_PRIORITY_IDLE
2Idle class, THREAD_PRIORITY_LOWEST
3Idle class, THREAD_PRIORITY_BELOW_NORMAL
4Idle class, THREAD_PRIORITY_NORMAL
5Background normal class, THREAD_PRIORITY_LOWEST
Idle class, THREAD_PRIORITY_ABOVE_NORMAL
6Background normal class, THREAD_PRIORITY_BELOW_NORMAL
Idle class, THREAD_PRIORITY_HIGHEST
7Foreground normal class, THREAD_PRIORITY_LOWEST
Background normal class, THREAD_PRIORITY_NORMAL
8Foreground normal class, THREAD_PRIORITY_BELOW_NORMAL
Background normal class, THREAD_PRIORITY_ABOVE_NORMAL
9Foreground normal class, THREAD_PRIORITY_NORMAL
Background normal class, THREAD_PRIORITY_HIGHEST
10Foreground normal class, THREAD_PRIORITY_ABOVE_NORMAL
11High class, THREAD_PRIORITY_LOWEST
Foreground normal class, THREAD_PRIORITY_HIGHEST
12High class, THREAD_PRIORITY_BELOW_NORMAL
13High class, THREAD_PRIORITY_NORMAL
14High class, THREAD_PRIORITY_ABOVE_NORMAL
15Idle, normal, or high class, THREAD_PRIORITY_TIME_CRITICAL
High class, THREAD_PRIORITY_HIGHEST
16Real-time class, THREAD_PRIORITY_IDLE
22Real-time class, THREAD_PRIORITY_LOWEST
23Real-time class, THREAD_PRIORITY_BELOW_NORMAL
24Real-time class, THREAD_PRIORITY_NORMAL
25Real-time class, THREAD_PRIORITY_ABOVE_NORMAL
26Real-time class, THREAD_PRIORITY_HIGHEST
31Real-time class, THREAD_PRIORITY_TIME_CRITICAL


    Suffice it to say that exactly how the machine responds to pushing DMDX's priorities through the roof will fluctuate from version to version of win32, nay, even with different installs of the same win32 version, so I give you have option of tweaking them rather than me determining something now that will need changing later (especially as Microsoft reserves the right to change the above table as they see fit, already I notice that a Real-time class, THREAD_PRIORITY_TIME_CRITICAL thread is not priority 31 anymore but 39 instead). As I examine the processes and their threads on my test box (with PVIEW95.EXE) I see that most processes have the NORMAL_PRIORITY_CLASS, there are two exceptions DDHELP.EXE, the DirectDraw helper, a real time process and KERNAL32.DLL, the heart of the OS, a high priority process. DDHELP has two threads, and idle thread (at 9) and a normal thread (at 24) and the kernal has threads ranging from lowest (13) to time critical (28).
    Depending on how the DMDX process priority is set and how the retrace thread's priority is set various parts of the operating system (of which DirectX and therefore DDHELP is a part) are preempted by DMDX, sometimes a good thing, sometimes a bad thing. For instance, if I set DMDX to REALTIME_PRIORITY_CLASS and the retrace thread to THREAD_PRIORITY_TIME_CRITICAL the back buffers were no longer cleared correctly so that's too high, a bad thing on my test system, maybe your machine will behave differently.
   
   
    There are numerous possibilities here, the first of which is that assuming you can set the retrace thread at a priority level that makes it preempt the rest of the machine without bombing something else and you have a video card that handles a flip very close to the next retrace (not all video cards can handle this, the cause of the n milliseconds of refused flips message) you can then set (indeed, you may have to set) a very long sleep time, nearly the duration of the refresh interval, for the retrace thread. You will probably also need to reduce the maximum blit size when doing this as a blit in progress is still likely to block the retrace thread.

    It currently looks like DirectX just ups the ante when DMDX boosts itself, possibly not a bad thing because then DirectX might stop functioning if it didn't up it's priority.




TimeDX Index.