screensaver hurts CUDA performance? - performance

I've noticed that the running times of my CUDA kernels are almost tripled the moment the screensaver kicks in. This happens even if it's the blank screensaver.
Oddly enough, this appears to have nothing to do with the power settings. When I disable the screen saver and let the screen power off, the performance stays the same. When I set the "Turn off monitor" to "Never" and lets the screen saver kick in, it happens.
Why does this happen?
Is there a way to counteract this phenomena?
Is there a way to tell windows not to kick in the screen saver? (How do media players do it?)
I'm working on XP SP2 x64

Firstly, its interesting that CUDA is so impacted.
But here is the recipe in win32 for avoiding the screensaver kicking in:
A normal approach is to send yourself 'fake' key presses occasionally using the SendInput API, to reset the inactivity timer that triggers the screensaver.
It is possible to stop applications doing this, however, using the SPI_SETBLOCKSENDINPUTRESETS parameter for SystemParametersInfo.
Another approach is just to turn the screensaver off programmatically, using SPI_SETSCREENSAVEACTIVE for SystemParametersInfo. However, this is a global setting for the whole user - what if two programs use this overlapping? Try to avoid this!

Related

Intercepting a window's attempt to steal global focus on Windows

I'm a developer and a long-time Windows user with an obsession about making my system as convenient to use as possible.
Yesterday I thought about something that has always annoyed me in Windows and that I've taken for granted, and I realized that I have a better idea for how it could work, and I'm now wondering whether it's possible to tweak Windows to work like that.
The thing that annoys me is when windows steal focus. For example, I could be running an installer for some program. While it's working, I'll switch to my browser and browse, maybe entering some text into an email in my browser. Then suddenly the installer finishes and its window steals the focus. Now I'm in the middle of writing an email, so I might press a key that happens to be bound to a button on that installer, and then that button gets invoked, doing some action that I never intended to happen!
This is doubly annoying to me because I'm using a multiple-desktop program called DexPot, and when a window steals focus, it also brings itself to the desktop I'm currently on, which can be really annoying, because then I have to put it back into its original desktop.
How my ideal solution to this problem would work: Every time a window tries to steal focus, we intercept that, and don't let it. We show something like a toaster message saying "Foobar installer wants focus, press Win-Whatever to switch to it". If and when you press the key combo, it switches to the window.
The question is: Is there an easy way to tweak Windows to make this happen? I know very little about Windows programming. I do know AHK and if it's possible with that, that'd be great.
No, there isn't an easy way to add this behavior, but Windows tries to do this automatically.
In theory apps shouldn't be able to steal the foreground while you're actively using another app. Unfortunatly there are some scenarios where Windows can't tell the difference between legitimate user actions that should change the foreground and unwanted foreground-theft. The window manager generally tightens up the holes a bit with each new version of Windows, but also needs to make sure that apps can come to the foreground when the user wants them to, even if that desire is expressed indirectly.
For example, a process launched by the current foreground process can put a window into the foreground. This is necessary so that when a user launches a window from Explorer the newly launched process can open its main window. This permission only lasts until the next user input, so if an application is slow to launch and you start working on an email the app may lose its foreground permissions before it can use them.
See the SetForegroundWindow function documentation for a list of requirements for a process to be able to set a window into the foreground.
There are also apps which specifically make use of these requirements to steal the permission (by joining the foreground queue or synthsising user input to themselves), but I suspect in your installer scenario it is accidental.
I'm not sure what exactly is going on, but I suspect that the problem comes from the installer running as a service and accidentally stealing the foreground permission when it tries to launch the app on your current desktop.
It would be theoretically possible for an external process to hook into the foreground system to override this and show your confirmation toast, but it would be tricky to get right and would require significant low level code (I'd probably start with a CbtHook). It would not be possible in a scripting package like AHK (assuming you mean AutoHotKey) but would need to be native C/C++ code injected into every running process.

discontinuous BitBlt capture

I am using BitBlt heavily in my project. I create a number of threads and in each thread I capture the screen by BitBlt. It works great and as expected for now except the following problem.
The problem happens when the user clicks on a running program or for example already opened explorer on the taskbar. You know when you click on the running program on the taskbar, it either minimizes or appears on the screen. The issue that I am talking about happens just in this transition. At that moment, something like an interrupt, all threads stop capturing the screen for a fraction of a second and then they continue capturing. The same thing happen when you move down or up the thing on the volume control window. Could you please shed some light why this is happening and how I can prevent this happening?
Thanks.
Jay
It could be a scheduling issue. When you activate an app, it gets a small, momentary boost in its priority (so that it can seem responsive in the UI). This boost might last about as long as the animation and momentarily pre-empt your screen capture threads.
It's also possible that the desktop manager is serializing stuff, and your bitblts are simply stalled until the animation is over. Even if you've turned Aero off, I believe the desktop window manager may still be in compositing mode, which has the effect Hans Passant was describing in the comments.
If you're trying to make a video from the screen, I think it's going to be impossible to rely on GDI. I strongly suggest reading about the Desktop Window Manager. For example, this caveat directly applies to what you're trying to do:
Avoid reading from or writing to a display DC. Although supported by DWM, we do not recommend it because of decreased performance.
When you use GDI to try to read the screen, DWM has to stop what it's doing, possibly render a fresh copy of the desktop to video memory, and to copy data from video memory back to system memory. It's possible that the DWM treats these as lower-priority requests than an animation in progress, so by the time it responds to the BitBlt, the animation is over.
This question suggests that DirectShow with a screen capture filter might be the way to go.

How to extend the app timeout in Win 7?

My program is for rendering an animation clip, but every frame has to be computed before rendered. It seems that if the computation takes seconds, windows starts to recognize my process as "not-responding" and refuses to render anything any more, although in the Task Manager, the process itself appears to switch between "running" and "not-responding" all the time.
I have been searching solutions online for a while. A lot people suggested to delete some registry entries:
HKEY_USERS.DEFAULT\Control Panel\Desktop\HungAppTimeOut
HKEY_USERS.DEFAULT\Control Panel\Desktop\WaitToKillAppTimeOut
HKEY_CURRENT_USER\Control Panel\Desktop\HungAppTimeOut
HKEY_CURRENT_USER\Control Panel\Desktop\WaitToKillAppTimeOut
HKEY_CURRENT_USER\Control Panel\Desktop\WaitToKillServiceTimeOut
But I could not find those entries. And according to the descriptions, all those entries mentioned are about controlling how long the system waits after the user requires to end a process or log off to kill a process or service. So they are not what exactly I want. I guess there must be some threshold to control when the system should start to consider one process as "not responding" and I want to change that threshold into a slightly bigger one.
Thanks for your attention and time, any suggestion is welcome!
You should avoid hanging the UI in the first place by doing your processing/computation in a background thread, rather than on the UI thread. If you're using WinForms or WPF, use a BackgroundWorker.
See here for some BGWorker examples: WPF Threads: Build More Responsive Apps With The Dispatcher
I'm using Microstation to build a model, so this is a similar process. About half way through building the model everything freezes up and adds the "application not responding" message to the title.
Disabling the Desktop Window Manager Session Manager worked for me, however in a enterprise environment this is not the best solution, as common users don't have rights to access the services panel.
Try disabling Desktop Window Manager Session Manager from services. Worked for me. That also disabled aero theme by the way. Win7 really looks fancy but it has to operate normally.

Create a Program that Sits in The Windows Taskbar and, When Activated, Stops the Screensaver From Starting

I don't really know where to begin. Let's start with the stupid questions:
What language should I use for this? What is suited for the task at hand?
Next, the real ones:
Is there a way to stop the screensaver from starting, short of changing the cursor position? If not, will changing the cursor position even work?
SetThreadExecutionState will prevent the screensaver from coming on or the machine from automatically going to sleep if you pass the ES_CONTINUOUS and ES_DISPLAY_REQUIRED flags.
I wrote an app awhile ago that does exactly what you are asking for. It runs as an icon in the System Tray, not the Taskbar, and uses a global message hook to disable the WM_SYSCOMMAND/SC_SCREENSAVE notification from reaching any applications. If that notification does not reach the DefWindowProc() function, the screen saver will never run.
Your program does not need to be visible in the task bar at all.
You don't even need a program at all, if you can disable the screensaver in the registry.
What you want to do can perhaps be achieved by sending a MOUSE_MOVE event to the desktop window. If you want to use C# (the only language I am current with right now), you can look at this article, but maybe a simple C program using the WinAPI is better suited for this task.
.NET will easily allow you to put an application in the system tray (checkout the NotifyIcon object in System.Windows.Forms.Controls).
I believe you can use the SetCursorPos (http://msdn.microsoft.com/en-us/library/ms648394(VS.85).aspx) API call to prevent the screen saver, just make sure you set them to the current location so you don't actually move the mouse.

How to determine that a screensaver is running?

One solution that one could suggest is to periodically look for a special 'Screen-saver' desktop, and if it's present then count it as a running screensaver.
But apparently this is not the case for all screensavers as with some the mentioned desktop is always present.
Are there more reliable solutions for this?
See the WINAPI function SystemParametersInfo() with the SPI_GETSCREENSAVERRUNNING parameter. It's the only documented way to detect whether the screen saver is currently running. (You can also find out if a screen saver is even enabled, get and set the timeout value, and start the screen saver using this function.)
I think the key is to identify the screensaver by its window class ("WindowsScreenSaverClass"). I found this page
How do I start, detect and stop screen savers? that has some code examples and explanations.
HOW TO: Determine If Screen Saver Is Running by Using Visual Basic 6.0
I know this is for VB6, but it's bound to be a good place to start.
This is my implementation of screen saver event detection.
Notes:
SPI_GETSCREENSAVERRUNNING detects Windows Event id 4802 and 4803 which weren't accurate in my case, see my problem hence user idle time calculation is added
GetLastInputInfo apparently doesn't work if process is a service.
search processes for a process with .scr in its .MainModule.FileName

Resources