Home > Enterprise >  Is there a way to programmatically find the current used GPU (C, C )?
Is there a way to programmatically find the current used GPU (C, C )?

Time:12-16

In the case of CPUs, the (linux specific) sys calls getcpu() or sched_getcpu() can be used inside a program to obtain the ID of the core executing them. For example, in the case of a 4 processors system, the logical index returned by the mentionned calls makes it possible to deduce which one of the 4 CPUs is being used (let's say every CPU contains 10 cores, therefore if sched_getcpu() returns 20, that means the CPU #2 is being used since the core number 20 is in the 3rd CPU).

How can I achieve a similar thing in the case of GPUs? Is there a way to find which one is being used in real time from inside an application?

CodePudding user response:

C has no concept of a GPU. You got a great comment pointing you to the right direction of getting some GPU info using OpenGL, I'm sure there are other cross platform libraries as well.

Take a look at the source code of neofetch which is a command-line system info tool which, among other things, gets your GPU(s). It uses a bunch of different methods to get the GPU on the current system, some of which may help point you to the right direction. For example, for linux systems it gets the gpu info using lspci -mm:

echo $(lspci -mm | awk -F '\"|\" \"|\\(' \
'/"Display|"3D|"VGA/ {
a[$0] = $1 " " $3 " " ($(NF-1) ~ /^$|^Device [[:xdigit:]] $/ ? $4 : $(NF-1))
}
END { for (i in a) {
if (!seen[a[i]]  ) {
sub("^[^ ]  ", "", a[i]);
print a[i]
}
}}')

which returns NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] for my system. But this is not cross platform. If you wanted to do it yourself you would thus have to either:

  • implement a way for every system your application will run on
  • lose cross-platform ability

Or simply use OpenGL as mentioned above.

CodePudding user response:

It depends on the API you are using to access the GPU. Under vulkan, the capability to query the available devices is provided in the API itself. e.g.

vkEnumeratePhysicalDevices    //< use to iterate over devices 
vkGetPhysicalDeviceProperties //< use to determine make/model
vkGetPhysicalDeviceFeatures   //< use to determine the capabilities

Under OpenGL, this is a little harder, because the API doesn't really provide a nice robust way of iterating over connected GPU's (this is very much left to the underlying OS). Aside from calling glGetString with GL_VENDOR, and/or GL_RENDERER, after the context has been created, that's about all you have got.

With graphics API's in general, you will typically choose the device to use up front, and then forget about it. (i.e. you know which GPU is in use, because it's the one you requested)

So for example, on windows you'd use the WIn32 API call EnumDisplayDevices to iterate over a bunch of DISPLAY_DEVICE structures, which give you a breakdown of the GPU devices. If you then want to query the device capabilities, you'd need to initialise an OpenGL context (with the correct device), and make multiple calls to glGetIntegerv to query the actual capabilities.

Sadly, on linux this is a little trickier. Iterating the display devices is pretty much going to depend on the underlying API you are using to initialise the GPU (e.g. GLX, SDL, Qt, etc).

So for example, in SDL you would iterate over the available devices using SDL_GetRenderDriverInfo, before passing your preferred device index to SDL_CreateRenderer at app startup.

  • Related