Process priority and unterrupted playback

Started by j7n, May 31, 2016, 00:17:11

Previous topic - Next topic

j7n

I have recently updated from classic ModPlug Tracker to OpenMPT, and cannot configure the program to deliver uninterrupted playback unless it is pretty much the only software running. Still, there occasionally are clicks when I switch tabs on the main interface. The main reason here is that I have an older computer running Windows XP. However, on my machine Reaper and Renoise are rock solid even at low latencies of 10-35 ms, out of the box.

I can use either DirectSound or E-MU ASIO driver, without much difference.

Further investigation of the other two applications reveals that they have threads that do heavy work running at priority 15 (max), and old ModPlug was by default at High process priority, threads at 14. (Reaper also effectively locks up the system while rendering, which I can deal with.) OpenMPT's priority by default is 8 or 9 (with 'Boost thread priority').

Setting the process priority of OpenMPT to high resolves the problem. But it is inconvenient to do. I would like to ask to reinstate the old behavior as an optional Switch. It would be great if it dropped priority during rendering, but it's okay if it does not. Mods with this program use very little CPU on average.

Great software with efficient classic Windows look!

manx

#1
Quote from: j7n on May 31, 2016, 00:17:11
I have recently updated from classic ModPlug Tracker to OpenMPT, and cannot configure the program to deliver uninterrupted playback unless it is pretty much the only software running. Still, there occasionally are clicks when I switch tabs on the main interface. The main reason here is that I have an older computer running Windows XP. However, on my machine Reaper and Renoise are rock solid even at low latencies of 10-35 ms, out of the box.

In addition to your analysis about thread priorities (which is correct), you may also try to decrease the hardware acceleration of your graphics card. The setting is at: Start -> Settings -> Control Panel -> Display -> Settings -> Troubleshoot -> Hardware acceleration. Graphics drivers often use threads running at high priority which can interfere in the way you describe.

Quote from: j7n on May 31, 2016, 00:17:11
I can use either DirectSound or E-MU ASIO driver, without much difference.

I assume you mean both DirectSound and ASIO with OpenMPT here and not in Renoise or Reaper.

Quote from: j7n on May 31, 2016, 00:17:11
Further investigation of the other two applications reveals that they have threads that do heavy work running at priority 15 (max), and old ModPlug was by default at High process priority, threads at 14. (Reaper also effectively locks up the system while rendering, which I can deal with.) OpenMPT's priority by default is 8 or 9 (with 'Boost thread priority').

Setting the process priority of OpenMPT to high resolves the problem. But it is inconvenient to do.
Quote from: j7n on May 31, 2016, 00:17:11
It would be great if it dropped priority during rendering, but it's okay if it does not. Mods with this program use very little CPU on average.

Your analysis is correct.
There are 2 different aspects that come into play here (see https://msdn.microsoft.com/en-us/library/windows/desktop/ms685100%28v=vs.85%29.aspx), namely the process priority class (which applies to ALL threads of a process) and the individual thread priority.
I have not checked the code for old ModPlug, but if the effective thread priority is 14, then it almost certainly used (HIGH+ABOVE_NORMAL) (priority class and thread priority respectively).
Current OpenMPT used (NORMAL+ABOVE_NORMAL) which results in 9.
I just (in r6452) changed this to (NORMAL+HIGHEST) which results in 10 (you can find current test builds at https://buildbot.openmpt.org/builds/). (note: there is also TIME_CRITICAL which would boost directly to effective priority 15)

Please note that any thread running at roughly effective priority 11 or higher can (depending on various other aspects) completely lock up your system if it consumes 100% CPU, requiring a hard reset of your system. As we are also running potentially foreign code (i.e. VST plugins) in that thread, I do not as the default want to increase priorities further.

Changing the priority for WaveOut or DirectSound devices is totally simple as we own the thread.
Changing the thread priority for ASIO is probably even totally wrong as the thread actually belongs to the ASIO driver and we do not know whether it actually depends on the priorities it itself sets up for driver-internal scheduling purposes. Technically we could change its priority of course.
Changing the priority class for the whole OpenMPT process is also possible but that will move the audio thread above effective priority 10, which I, again, do not want to enable by default.

I can envision the following (some or all of them) options:

  • OpenMPT priority class (IDLE, BELOW, NORMAL, ABOVE, HIGH, REALTIME)
  • thread boost priority (IDLE, LOWEST, BELOW, NORMAL, ABOVE, HIGHEST, TIME_CRITICAL)
  • boost ASIO thread priority (on, off)
  • boost ASIO thread priority while running in driver code (on, off)

In any case, OpenMPT will (and currently does) only apply priority boosting while actually using the sound card and not while rendering to file.

Note for Vista+ users: Nothing here really applies to Windows Vista or later because we are using the Multimedia Class Scheduler (MMCSS) there instead of fiddling with raw priorities. Behaviour depends on the configuration of the system-wide MMCSS there. Defaults are sane (effective priority 14 with system overload protection).

Note for Wine users: Nothing at all applies there, because Wine completely ignores all thread priorities anyway.

Saga Musix

QuoteStill, there occasionally are clicks when I switch tabs on the main interface.
This is also a known but unsolved problem, for some reason the initial tab redrawing is much slower than with previous MFC versions, so I'm not sure if this can ever be as fast again as it was in MPT classic. That said, OpenMPT's output is pretty solid on my old (and slow) Win98 machine, so other drivers (like manx suggested) may very well come into play here.
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.

manx

Quote from: Saga Musix on May 31, 2016, 08:06:14
QuoteStill, there occasionally are clicks when I switch tabs on the main interface.
This is also a known but unsolved problem, for some reason the initial tab redrawing is much slower than with previous MFC versions, so I'm not sure if this can ever be as fast again as it was in MPT classic. That said, OpenMPT's output is pretty solid on my old (and slow) Win98 machine, so other drivers (like manx suggested) may very well come into play here.

Well, it's also actually not at all solid on my Windows 7 box with 2 different generation AMD GFX cards running 2 screens each. I did never investigate this any further as this is a rather unusual setup. I have not yet checked if boosting priorities further actually helps there (I guess it might). Thus, more options in that direction may be worthwhile. Windows 7 if of course the same situation as Vista and I am now quite sure what the precise interactions of MMCSS and process priority class are.


manx

Quote from: Saga Musix on May 31, 2016, 08:06:14
That said, OpenMPT's output is pretty solid on my old (and slow) Win98 machine,

Well, the Win 9x scheduler also behaves completely differently compared to the Win NT scheduler used by NT4 up to Windows 7 (IIRC, Windows 8 got a major overhaul there).

manx

I added the following to r6454:

Changelog:

[New] Allow setting the process priority class. The hidden setting and default is [Misc]ProcessPriorityClass=normal. Fixes https://forum.openmpt.org/index.php?topic=5655.0 .
[Imp] sounddev: Allow setting the priority (XP) or MMCSS class (Vista) used for boosting the sound device thread. The hidden options and defaults are [Sound Settings]BoostedThreadPriority=2" and [Sound Settings]BoostedThreadMMCSSClass="Pro Audio". Fixes https://forum.openmpt.org/index.php?topic=5655.0 .
[Imp] sounddev: ASIO: Add possibility to override the thread priority imposed by the ASIO driver. The hidden setting and default is [Sound Settings]ASIODriverThreadPriorityOverride=false. Fixes https://forum.openmpt.org/index.php?topic=5655.0 .
[Mod] OpenMPT: Version is now 1.26.02.02

Manual additions:

[Misc]
* ProcessPriorityClass: Set the Windows process priority class for OpenMPT. Possible values are: "idle", "below", "normal", "above", "high", "realtime". The default is "normal". See further discussion at https://forum.openmpt.org/index.php?topic=5655.0 . Warning: Changing this setting can cause system lockups requiring hard system reset.

[Sound Settings]
* BoostedThreadPriority: Set the priority (for Windows XP and earlier) used for sound devices which have "Boost thread priority" set. Possible values are -15,-2,-1,0,1,2,15 (or the full range -15..15 if [Misc]ProcessPriorityClass is set to "realtime"). Default value is 2. See further discussion at https://forum.openmpt.org/index.php?topic=5655.0 . Warning: Changing this setting can cause system lockups requiring hard system reset.

[Sound Settings]
* BoostedThreadMMCSSClass: Set the Multimedia Class Scheduler Service (MMCSS) class (for Windows Vista and later) used for sound devices which have "Boost thread priority" set. Possible values are "Pro Audio", "Games", "Audio" or anything else that may be configured on your systems MMCSS. Default value is "Pro Audio". See further discussion at https://forum.openmpt.org/index.php?topic=5655.0 . Warning: Changing this setting can cause system lockups requiring hard system reset.

[Sound Settings]
* ASIODriverThreadPriorityOverride: Apply priority override to the thread spawned by the sound card ASIO driver. This will overwrite the piority set by the driver with the priority specified in [Sound Settings]BoostedThreadPriorityXP. This setting may also be used to actually reduce the priority. See further discussion at https://forum.openmpt.org/index.php?topic=5655.0 . Warning: Changing this setting can cause system lockups requiring hard system reset.

manx

So, I guess setting [Misc]ProcessPriorityClass=high (or [Misc]ProcessPriorityClass=above) OR possibly setting [Sound Settings]BoostedThreadPriority=15 would solve your problems, right?

Restart OpenMPT after changing process priority and switch back and forth between sound devices for the other settings in order for them to take effect.

I would recommend staying with only boosting process priority if it solves your issue. [Sound Settings]BoostedThreadPriority will not have an effect on ASIO unless you also set [Sound Settings]ASIODriverThreadPriorityOverride=1 which in itself is not guaranteed to actually work, depending on when exactly the driver enforces the thread priority.
Realtime priorities also have a real danger of completely locking up your sytsem in case of any bugs or high CPU load plugins, thus handle [Misc]ProcessPriorityClass=realtime and [Sound Settings]BoostedThreadPriority=15 with appropriate care.

j7n

#7
Thank you for the update. I have tried the latest builds. Either ProcessPriorityClass = high or BoostedThreadPriority = 15 resolves the problem when using DirectSound!

Apparently ASIO was already working at top priority in the release version. I thought I had tried it and found the opposite but clearly I was wrong. This priority cannot be reduced. That is ok. Process Explorer relates this thread to ctasio.dll (E-MU / Creative).

I tried adding a VST that is known not to be realtime. The mouse movement becomes very jittery, but it is still possible to stop playback and remove the effect. High combined with boost = 1 (resulting priority of 14) make it much easier to stop playback.

The option "play silence" under ASIO driver is very useful. This driver has a huge CPU usage spike in all applications when it is opened. That is possibly related to its priority.

I found a little problem with OldWin builds. It is not possible to edit any value (aside from bool) under Setup > Advanced. When I double-click something, I get a huge empty window that extends outside the screen. In release 1.26 I get a smaller empty window, in 1.25 I get the correct text box. I tried the lated Win7 test build (on XP), and it didn't have this issue.

manx

Quote from: j7n on June 01, 2016, 05:23:04
I found a little problem with OldWin builds. It is not possible to edit any value (aside from bool) under Setup > Advanced. When I double-click something, I get a huge empty window that extends outside the screen. In release 1.26 I get a smaller empty window, in 1.25 I get the correct text box. I tried the lated Win7 test build (on XP), and it didn't have this issue.

In the future, please open a new topic or even better an issue in the bug tracker (https://bugs.openmpt.org/) for each individual issue. That makes it easier for us to keep track and not miss, forget or confuse things.
I added the issue at https://bugs.openmpt.org/view.php?id=810.

manx

Quote from: j7n on June 01, 2016, 05:23:04
Thank you for the update. I have tried the latest builds. Either ProcessPriorityClass = high or BoostedThreadPriority = 15 resolves the problem when using DirectSound!
Great.

Quote from: j7n on June 01, 2016, 05:23:04
Apparently ASIO was already working at top priority in the release version. I thought I had tried it and found the opposite but clearly I was wrong. This priority cannot be reduced. That is ok. Process Explorer relates this thread to ctasio.dll (E-MU / Creative).
Yeah, that's what I had assumed anyway. An ASIO driver not setting some higher thread priority would have been rather strange.

Quote from: j7n on June 01, 2016, 05:23:04
I tried adding a VST that is known not to be realtime. The mouse movement becomes very jittery, but it is still possible to stop playback and remove the effect. High combined with boost = 1 (resulting priority of 14) make it much easier to stop playback.
That matches the expected results.

Quote from: j7n on June 01, 2016, 05:23:04
The option "play silence" under ASIO driver is very useful. This driver has a huge CPU usage spike in all applications when it is opened. That is possibly related to its priority.
Huge CPU usage spikes when loading/starting/stopping/closing ASIO drivers are generally unrelated to their thread priority. Frankly, it's just stupid drivers. There should not be any reason to cause huge CPU usage spikes.
But stupid drivers do exist, and that's precisely the reason why this option exists ;-)

Quote from: j7n on June 01, 2016, 05:23:04
I found a little problem with OldWin builds. It is not possible to edit any value (aside from bool) under Setup > Advanced. When I double-click something, I get a huge empty window that extends outside the screen. In release 1.26 I get a smaller empty window, in 1.25 I get the correct text box. I tried the lated Win7 test build (on XP), and it didn't have this issue.
Fixed in r6460 now.

j7n

How is it that an output driver can change how (at which priority) effects processors get executed? VSTs run equally otherwise regardless of driver.

Saga Musix

VSTs run in the audio thread, hence changing the overall process priority and the audio thread priority in particular will also change the priority of anything that is being done in the audio process (i.e. mixing and plugin processing). There is no such thing as just boosting the thread priority for the actual audio output but not the mixing process. It could be separated into two independent threads in theory, but this is not what OpenMPT does and I'm not even sure if it would benefit anyone - at least not until OpenMPT can do multithreaded plugin rendering.
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.

manx

Quote from: Saga Musix on June 02, 2016, 12:05:07
It could be separated into two independent threads in theory, but this is not what OpenMPT does and I'm not even sure if it would benefit anyone - at least not until OpenMPT can do multithreaded plugin rendering.

Separating into 2 independent threads would require another layer of buffering and thus will just increase latency for practically no gain at all.

Separating into 2 dependent threads would also be an option and may actually have some use as we would be able to detect buffer underruns independent of the driver API used. This way, stalling the driver in case of system overload could also be avoided which would benefit again some driver APIs. However, I currently have no plan to implement that. The gains are not worth the effort.

Additionally, there is a mode in which an ASIO driver can request the application to use a separate thread for rendering. OpenMPT currently ignores this request (violating the ASIO specification) because as far as I know, we have not yet seen any driver actually requesting that in the wild.

In any case, potential multi-threaded plugin rendering or mixing is completely independent from how exactly threading works for audio output. Coupling these two aspects would only over-complicate things, in my opinion.

manx

Quote from: j7n on June 02, 2016, 10:15:42
How is it that an output driver can change how (at which priority) effects processors get executed? VSTs run equally otherwise regardless of driver.
Another note: If effects processing would run at lower priority than the actual audio output thread, then it again would be subject to interruptions from other system threads. I.e. there is no workable way to just lower the priority for effects without sacrificing all advantages gained from high priority (i.e. low latency and drop-out resilience) in the first place.

Saga Musix

QuoteSeparating into 2 independent threads would require another layer of buffering and thus will just increase latency for practically no gain at all.
Not necessarily no gain at all - in some specific situations we could benefit from this, e.g. when using plugin bridging: By implementing this and plugin delay compensation, we could trade all the synchronisation overhead in the plugin bridge with latency, so that audio output would be more stable when using tons of bridged plugins. But yeah, just having a separate thread without what I just said or you said in your post is not going to help anyone.
» No support, bug reports, feature requests via private messages - they will not be answered. Use the forums and the issue tracker so that everyone can benefit from your post.