AIRLegend / aitrack

6DoF Head tracking software
MIT License
1.03k stars 102 forks source link

Always prioritize aitrack's graphical priority over games #178

Closed GoldJohnKing closed 1 month ago

GoldJohnKing commented 1 year ago

Describe your idea

There is a potential performance issue on aitrack.

On Windows, the top window always has the highest graphical priority over other windows.

While games' window is on top, the performance of aitrack would greatly decrease if the game consume too much GPU resources, causing the head tracking report rate stuttering. (For example, DCS World with highest graphical settings on an 3080 card.)

Describe the solution you'd like

Luckily, we can call some Win32 API to prioritize aitrack over games.

The side effect would be, the game instead of aitrack, might drop some fps.

I have made a side-loaded DLL with some hooks that can do this.

I would like to know if you like the idea. If you do, I could give a try to integrate it directly into aitrack.

Describe alternatives you've considered

We may add an option and let user choose enabling the feature or not.

If it is not possible or too difficult to integrate the feature into aitrack, airtrack could just load the dll, then the feature would be on.

Additional context

This is the rough demo I made, you may check out the code here.

https://github.com/GoldJohnKing/GpuPriorityBooster

searching46dof commented 1 year ago

Thanks for your contribution. It's up to AIRLegend if he wants to add it to his master tree but you can always make a fork and then add your changes to the fork.

However, I believe windows provides the capability to configure these parameters. You can set the priority for the foreground app or background (https://www.technipages.com/windows-10-set-cpu-priority-to-prefer-foreground-apps#:~:text=You%20can%20open%20this%20menu,%3A%E2%80%9D%20is%20set%20to%20Programs.) You can set the priority and cpu affinity with regedit (https://answers.microsoft.com/en-us/windows/forum/all/how-to-permanently-set-priority-processes-using/2f9ec439-5333-4625-9577-69d322cfbc5e) You can set the priority and cpu affinity with a shortcut (https://answers.microsoft.com/en-us/windows/forum/all/how-to-permanently-set-priority-affinity-with/4e83fd39-34a7-49fe-a54a-ee891c38b737)

Is this "a potential issue" or actual symptoms that you are experiencing? The reason I ask is that I'm running DCS on Ryzen 5700g with RTX 3060 (both at stock settings) at 4K with highest non-VR graphical settings. Although the GPU is maxed out, the total CPU utilization is around 30-35% and one or 2 individual CPUs may reach a momentary peak of 80%.

If your system is CPU starved (total CPU ~100%), raising the priority of one process may cause additional issues. e.g. You would also need to also raise the priorty of opentrack otherwise it raising the priority of aitrack would not be effective. But then you would also need to raise the priority of antivirus which is running under the context of opentrack and aitrack. You would also need to raise the priority for software supporting the mouse and keyboard and also the wireless subsystem if they are wireless (e.g. bluetooth). And don't forget the software supporting the joystick/throttle otherwise they would become unresponsive. And so on... If there is insufficient idle time, then "something's got to give". It's better to try to find the source of the high CPU and then try to reduce it.

It may be hardware related. You may need to check the BIOS,chipset and other drivers are up to date and the CPU is running cool enough to prevent throttling. You may need to check the camera is suffiicently powered and running at USB3 speeds.

It may be software related. You can shut down non-essential background apps and add antivirus exclusions.

It may be configuration related. Since you mention a high bandwidth condition, verify the FSB and memory bandwidth are configured correctly. You can also reduce the webcam resolution to reduce the requirements. And verify the RTX 3080 is running in the fastest PCIe slot.

It may be a mismatched CPU/GPU hardware combination causing the high CPU. (e.g. running a RTX3080 on an AM2 system. Although the CPU is fast enough it doesn't have enough bus bandwidth for 4K gaming)

And if an individual CPU is maxing out, a simpler solution would be setting the CPU affinity. (e.g. CPU1=aitrack/opentrack, CPU2=DCS and leave CPU0 for interrupts). If CPU affinity does not solve that symptom, then the CPU may not be quick enough.

In either of these cases, it may be better to reduce the requirements (e.g. running at 2K or 1440 and lowering the graphical settings) otherwise it usually indicates a hardware upgrade is necessary.

GoldJohnKing commented 1 year ago

Thanks for your contribution. It's up to AIRLegend if he wants to add it to his master tree but you can always make a fork and then add your changes to the fork.

However, I believe windows provides the capability to configure these parameters. You can set the priority for the foreground app or background (https://www.technipages.com/windows-10-set-cpu-priority-to-prefer-foreground-apps#:~:text=You%20can%20open%20this%20menu,%3A%E2%80%9D%20is%20set%20to%20Programs.) You can set the priority and cpu affinity with regedit (https://answers.microsoft.com/en-us/windows/forum/all/how-to-permanently-set-priority-processes-using/2f9ec439-5333-4625-9577-69d322cfbc5e) You can set the priority and cpu affinity with a shortcut (https://answers.microsoft.com/en-us/windows/forum/all/how-to-permanently-set-priority-affinity-with/4e83fd39-34a7-49fe-a54a-ee891c38b737)

Nope, they are not the same "priority". Windows has many priority, What I said is the D3DKMT_SCHEDULINGPRIORITYCLASS. I believe it is not a public API already exposed and documented by Microsoft.

searching46dof commented 1 year ago

The priorities you mentioned are published at https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/d3dkmthk/ne-d3dkmthk-_d3dkmt_schedulingpriorityclass. The corresponding D3DKMTSetProcessSchedulingPriorityClass api is https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/d3dkmthk/nf-d3dkmthk-d3dkmtsetprocessschedulingpriorityclass

These are just duplicate apis for setting windows process priorities as SetPriorityClass: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setpriorityclass

If you check the function prototype: NTSTATUS D3DKMTSetProcessSchedulingPriorityClass( [in] HANDLE unnamedParam1, [in] D3DKMT_SCHEDULINGPRIORITYCLASS unnamedParam2 ); you will notice the extra parameter: [in] unnamedParam1 A handle to the process that scheduling priority is set for. and the URL: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/d3dkmthk/nf-d3dkmthk-d3dkmtsetprocessschedulingpriorityclass

vs Sets the priority class for the specified process. This value together with the priority value of each thread of the process determines each thread's base priority level. BOOL SetPriorityClass( [in] HANDLE hProcess, [in] DWORD dwPriorityClass ); and the extra parameter [in] hProcess A handle to the process. The handle must have the PROCESS_SET_INFORMATION access right. For more information, see Process Security and Access Rights.

It is a duplicate API provided by the Windows DDK to "relatively safely" set the process priority from a driver as opposed to a user mode applicatioin.