Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unity: How to use all CPU cores for Camera.Render with Multi-threaded Graphics Jobs? Optimisations - not working?

How to use Multi-threaded Graphics Job optimisations?

I have a project (less of a game, more of an application) which uses many tens of cameras in a scene, all rendering at one time. (Don't ask why, it has to be this way!)

Needless to say, when running the application, this nearly maxes-out one CPU core since the rendering pipeline is single-threaded. It drops the frame rate very low as a result. (GPU, memory etc are well below 100% load - the CPU is the bottleneck here)

I was greatly relieved to see that Unity has an option called "Graphics Jobs (experimental)" which is specifically designed to split the rendering across multiple threads, and as such, multiple cores.

However, with this option enabled and DirectX12 set at the top of the graphics APIs list, I would expect that the CPU can now be fully utilised, namely all CPU cores can be engaged in active rendering. However, it seems to still be that the application is still only utilising around 40% of my CPU's potential whilst delivering a low frame rate. Surely, it should only drop the frame rate once it has maxed out the CPU? It doesn't seem that the individual cores are being used any differently. Why can I not maximise the output frame-rate by utilising close to 100% of all cores on my CPU (in total, including any additional programs which are running)?

Essentially I would like to know how I can get Unity to use all of my CPU cores to their full potential so as to get as high a frame rate as possible whilst having as many cameras in my scene at once... ...I thought Graphics Jobs would solve this? ...Unless I'm using them incorrectly or not using the correct combination of settings?

As an aside, my CPU is a i7-4790 @3.6ghz and my GPU is a 980Ti using DX12. 32gb of RAM.

like image 823
Ben Hayward Avatar asked Nov 07 '22 23:11

Ben Hayward


1 Answers

During camera render, your CPU has to talk to the GPU, in what is called a drawcall. Under the hood, Unity is already using a multi-threaded approach (ctrl+f "threads") to get the CPU to talk to the GPU, and this process of dealing out tasks to worker threads takes place in a black box. Note that, "Not all platforms support multithreaded rendering; at the time of writing, WebGL does not support this feature. On platforms that do not support multithreaded rendering, all CPU tasks are carried out on the same thread."

So, if your application is bound by the CPU, then perhaps your platform is not supported, or the tasks simply can't be broken down into small enough chunks to fill up all your cores, or some other 'black box' reason, like maybe the CPU is iterating over each camera sequentially, instead of batching the bunch (this makes sense to me because the mainthread has to be the one to interface with the Unity API in a threadsafe manner to determine what must be drawn).

It seems that your only option is to read the links provided here and try to optimize your scene to minimize draw calls, but with that being said, I think trying to render 'tens of cameras' is a very bad idea to start with, especially if they're all rendering a complex scene at a large resolution with post processing, etc. - though I've never tried anything like it.

like image 50
Michael Curtiss Avatar answered Nov 15 '22 05:11

Michael Curtiss