mOfl's picture

Starting your application with the discrete GPU on NVIDIA Optimus systems

NVIDIA Optimus is an energy-saving technology that allows automatic seamless switching between an integrated and a discrete high-performant GPU in mobile devices. Unfortunately, the switching decision is currently based* on a profile system in which application profiles have to be created either by NVIDIA (pre-defined profiles for popular applications such as video games) or by the user.

* Informations regarding the switching system are sparse. According to the NVIDIA Optimus whitepaper, the discrete NVIDIA GPU is triggered by DX, DXVA and CUDA calls, but no OpenGL calls. From my experience, however, CUDA calls do not trigger the switching mechanism.

For a developer on an Optimus system, this is rather annoying since an own application profile has to be created for each GPU-intensive application. Even more annoying, every application user with an Optimus system has to create a
profile for the application, too, or else the application will use the integrated GPU, which might be inperformant or might not work at all because of missing hardware features.

SOP is a simple workaround for developers based on NVIDIA's NvAPI that creates an application profile for the current application such that it is always started using the discrete GPU. If the profile already exists, the
application is bound to the existing profile. Multiple applications can be gathered in one generic profile, thus keeping the profile system neat and tidy. The profile itself can also be edited in the NVIDIA Control Center.

- add SOP.cs to your application
- Call SOP_CheckProfile() at startup with the desired profile name to check if an Optimus profile of the specified name exists. If it does not, the user may be asked if it shall be created.
- Call SOP_SetProfile() with the desired profile name and the name of the executable. In the demo application, the generic profile name "OpenGL Developer Profile" is used.
Note: The switching depends on the filename, so all applications with the same name as the provided executable name will start with the discrete GPU.
- If the application profile was created or updated (SOP_Profile() returns SOP.RESULT_CHANGE) the application has to be restarted automatically or by the user.
- ?
- Profit

If you have to remove a profile, you can either do this manually in the NVIDIA Control Center or call the function SOP_RemoveProfile() from your application. Again, after changes have been made, the application has to be restarted for the changes to take effect, i.e. for the integrated GPU to kick in.

Demo application usage:

Syntax: SOP_Demo [-c | -s | -r]
    no arguments     Print device information for the current video card
    -c               Check if the Optimus profile exists
    -s               Set the Optimus profile and restart the application if necessary
    -r               Remove the Optimus profile and restart the application if necessary

Note: The OpenTK.dll included in the demo application is not needed for the functionality of SOP.cs. The OpenTK is only used to query video card information to indicate the success of video card switching.

Downloads (Last update: 12.11.2012)
- C# source file only
- Complete demo application with C# source code

This workaround is also available for C++:
- C++ header file only
- Complete demo application with C++ source code


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Sh4dd0w's picture

Is it normal that my program runs faster when in NVIDIA Control Center I select "use integrated grapgics card"?

mOfl's picture

No, this should not be happening in general. Does your application check for available extensions and maybe skips over code that is not supported on the current video card?

Sh4dd0w's picture

No, my app is pretty simple. It only draws a bit with GL and glControl. I can show you the code but it's less complicated than windows forms tutorial on this site

mOfl's picture

The integrated video card is always active in Optimus systems and the discrete GPU is only used to process the data and render it into the integrated GPU's buffer. Maybe your application is too simple such that the overhead of the discrete GPU is larger than the drawing overhead itself. A real performance difference should be visible as soon as you draw a lot and complex geometry and shading, e.g. a scene with a million polygons.

Sh4dd0w's picture

Exactly the same what I thought. Perhaps it is true. Thanks anyways

jingquan's picture

Thanks, this is useful.