How to keep running background threads at full power

I made a MacOS app that does a long calculation (a theoretical simulation) in a large number of GCD background threads. The calculation can take many hours and periodically updates the application's window to show intermediate results.

Performance is great as long as the application's window is visible: all cores at 100%, ventilator fan full blast, while the system remains completely responsive in other apps. I can still browse the web, watch videos, etcetera, but all excess power goes to the background threads which is great.

However, as soon as I completely cover my app's windows, performance drops to something like 30% and I can hear the fan slow down and even turn completely off. The same thing happens if I lock the screen (when I want to leave the computer unattended while the calculation is running).

What can I do to keep the computer from throttling down? I don't want to give the background threads real time priority because I want my computer to remain usable, but I do want to keep the computer as a whole at maximum power. Right now I try to keep a tiny corner of the app visible at all times, but there has to be a better way.

I'm using Grand Central Dispatch for the threads, so I hope there's a simple solution without requiring explicit thread management.

Thanks for any info!

Michel

Replies

Meanwhile I figured out the problem was due to app nap. So I tried disabling it in different ways I found on the internet:
  • plist item "NSAppSleepDisabled" YES: no difference, app still naps

  • [[NSProcessInfo processInfo] beginActivityWithOptions:NSActivityUserInitiatedAllowingIdleSystemSleep reason:@"Prevent app nap"]; // no difference, app still naps

  • App nap checkbox in the app's info window in the Finder: no such box?

I finally settled on disabling app nap for the whole computer via the terminal. This works, although it's not really ideal because now other apps cannot nap either, but at least I'm getting the performance I want:
defaults write NSGlobalDomain NSAppSleepDisabled -bool YES

If anyone can tell me how to disable it just for my app under Catalina, I would appreciate it.

Thanks,

Michel

Why NSActivityUserInitiatedAllowingIdleSystemSleep? It seems that NSActivityUserInitiated would make more sense here, in that you really don’t want the system to sleep while this work is in progress.

I'm using Grand Central Dispatch for the threads, so I hope there's a
simple solution without requiring explicit thread management.

I’d like to clarify this. Are you:
  • Using Dispatch to schedule a small number of blocks that then run for long periods of time?

  • Using Dispatch to schedule a bunch of blocks which, when combined, run for a long period of time?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

For Michel:

If anyone can tell me how to disable it just for my app under Catalina, I would appreciate it.

You can try: defaults write NSAppSleepDisabled -bool YES

where your domain is defined in your plist as CFBundleIdentifier. Then try defaults read and you should see NSAppSleepDisable=1;

This does not always work if you Hide your app.

John

For Michel,

My answer was truncated by the system. You should try defaults write your_domain NSAppSleepDisable -bool YES the system erased your_domain in my initial answer

John