shells-dw / streamdeck-totalmix

Unofficial StreamDeck RME TotalMix FX Plugin - supporting MIDI and OSC
MIT License
51 stars 5 forks source link

High CPU usage on Windows #26

Closed mvu closed 1 year ago

mvu commented 1 year ago

Hello,

I'm running the plugin (v3.3.4) on Windows 10 and the process "streamdeck-totalmix" shows a constant "very high" CPU usage. The plugin logs (also attached below) show some strange error: 2023-01-18 15:19:50.5747|INFO|de.shells.totalmix|3|Listener: catch main try: Object reference not set to an instance of an object.

After checking the source code (I am not a C# expert), it seems the Listener objects are not initialized inside the UpdateDeviceSettingDict function - but that would only be my wild guess :-)

Thanks!

pluginlog.log image

shells-dw commented 1 year ago

Hi, sadly due to the way RME implemented OSC in TotalMix, a lot of communication and processing has to be done, which in turn requires CPU time. Based on my own tests and feedback from other users I would assume you have a somewhat not very powerful CPU in your machine (be it because it's old or because it's a laptop or otherwise power consumption optimised PC and power saving is intentional) hence the load appears rather high (while 10% are not that high, I get your point). On my machine it's about 2-3%. The other option would be you set the "numbers of faders per bank" to more than 16 in the OSC Remote Controllers. If so, the load gets higher. If you don't really need/use so many channels, lower the channel count to the ones you use, despite what your interface may offer. If your interface offers 48 Channels per bank, but you use only 4 channels and the output, set it to 8 and spare the plugin of processing a couple of thousand values each second. Way less data needs to be processed that way. But anyhow. I tried to find a middle ground between mirroring performance and CPU load. Mirroring is kind of useless -for me anyway-, if it takes 5 seconds to mirror anything.

If that's too much load for you and you need all the channels that are set, the only option will be to disable mirroring. Then there will basically be no CPU usage at all anymore. Do disable mirroring, refer to the readme/config part and set mirroringRequested to false, save the config file, then restart StreamDeck.

Regarding the error message: TotalMix randomly closes the sockets it uses while my plugin still reads them (and then immediately opens them again, which is why the next query works again). This obviously causes an exception, which is caught, logged and then ignored, because there is nothing I can do when that happens. I can not look inside TotalMix so I don't know what's going on and why it does that, it just took me a while to even figure that out as it apparently happens completely randomly. On my machine it happens maybe once every 5 hours, on other days maybe once every 90 minutes, on other testing machines it happens every couple of minutes and I don't know why. Maybe there is a difference which device is connected, how much load this device or your computer has, how good your USB cable is, or any other setting influencing it - I don't know. I have my setup and with this setup I can test, I don't have access to other Firefaces or the time and interest in spending a month worth of work for every release I make of a free open source plugin I get basically nothing in return for. It does appear to happen rather constantly for you, which is interesting, but other than that it should not cause any issues for the plugin, as the data is updated on the next run then. Also, when disabling mirroring, this will also go away.

mvu commented 1 year ago

Hi, thank you for the detailed reply!

Thanks for the suggestion to disable mirroring. While it is quite convenient I will give it a shot, if it helps it would be a good sacrifice I can live with. And thank for you this amazing plugin!

shells-dw commented 1 year ago

Hi, thank you for the detailed reply!

sure, I could go more into detail why it is that way, but that would probably end in a rant about how RME uses OSC less as an API that could be queried for specific values an more like a MIDI implementation that just dumps data on request - and I feel like I've done this enough already in other issues.

* My CPU is a i7-5820K, each core running at 4GHz on a 850W tower PC. The CPU is already few years old but should be still quite performant. Almost all background processes stay at "Low Power usage" below 1% CPU utilization

Well, it depends what those background processes do, doesn't it? Put Prime95 in the background and it will still utilize 100% of your CPUs 😉 So long story short: the only way to get the status for the mirroring is to request a full bus dump of all settings. 3 times (once for input, playback/software and output), which adds up to a couple of hundred values each time, with more than 24 channels it's a couple of thousand values each time. Meaning the plugin has to parse hundreds to a couple of thousand values (depending how many channels you set) transmitted over a network protocol (UDP so there is no transmission control, hence everything has to be consistency checked too) by TotalMix per second, put them in a dictionary so it can react to changes that happened outside its control (aka "mirroring" where status changes made in the TotalMix UI are reflected on the StreamDeck) and parse the results (if actually something changed) - which each for it own isn't using that many CPU cycles, but all together in a basic constant loop adds up. One way to lower the CPU load would be to increase the gaps between the querys, make it sleep longer essentially, but that would result in delayed results. Having a change in the UI reflect on the StreamDeck 5 seconds after it's made, is kind of useless in my eyes. So the price to pay for the reduced latency is CPU cycles.

* I also noticed the impact of the "number of faders" configuration and played around with the values. At the time I wrote the first post, it was and is still set to 8 (is it possible to further decrease the value?) but the CPU spikes still occur.

nope, that is what TotalMix offers and puts out over OSC. I could in theory read and provide only 4 channels, but the amount of data that is transferred and would need to be processed stays the same as with 8, so there's not much point in doing that. I guess it makes sense they do the steps in which they sell interfaces, none has less than 8 channels per bank AFAIK.

* After further experimentation, it seems the spikes occur more frequently whenever I put PC into sleep mode and wake it up. The following procedure seems to help temporarily until the next sleep cycle (CPU usage drops to 1-2%):

  1. Kill both Totalmix and the streamdeck-totalmix plugin
  2. Restart both Totalmix + StreamDeck
     Do you have any tips how I could perform some further troubleshooting / debugging? I would be willing to spend a bit of time to find a root cause :-)

There seems to be strange things going on with TotalMix after the PC has been put to sleep. I have another user who has the issue that after putting his PC to sleep, TotalMix wouldn't starts its OSC Remote Listeners at all anymore and with the plugin not expecting that (before going to sleep mode everything was working fine and suddenly it isn't), it caused basically a deadlock or infinite loop. I should have avoided that with v3.3.3 though. So he had high CPU load because the plugin would go crazy, but also it would stop working. Now, I tried to reproduce that issue on my machine and I couldn't. I also asked a friend on mine to try that out, works just fine for him too. Not sure why TotalMix does that (and to be sure, this is a TotalMix issue, my plugin is just unable to connect anymore) and I'm not sure why it does different things on different machines, but then again I can't look in TotalMix and it appears to act differently on different machines anyway, looking at these unexpected socket closures. I do not have the slightest idea why this happens barely if at all for some and constantly for others.

That being said, I introduced a config flag killAndRestartOnStuck which will kill and restart TotalMix if set to true when it detects it not being responsive over OSC despite it should and has been (which is bascially what happens after you wake up the PC from sleep). The disadvantage of that is, again, gotta love TotalMix, that it doesn't save anything unless it's gracefully shut down, even config settings. So killing it would undo changes made to its settings. Unless you change settings that would not be an issue, just saying. You could give that a try to see if that resolves the after-sleep-issues.

Thanks for the suggestion to disable mirroring. While it is quite convenient I will give it a shot, if it helps it would be a good sacrifice I can live with. And thank for you this amazing plugin!

Sure buddy.