Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Shaders (vert & pixel) load high on CPU is normal?

Discussion in 'Shaders' started by april_4_short, Aug 2, 2021.

  1. april_4_short

    april_4_short

    Joined:
    Jul 19, 2021
    Posts:
    489
    Trying many different shaders, and examining their code, Unity seems to be bogging on the CPU, a lot, often.

    Am I wrong in presuming vert and pix shaders work exclusively on the GPU?

    Hard to tell, as I'm on a Mac, what's going on. Even builds with nothing but these sorts of demoscene style shaders are hitting the CPU 4x or 5x harder than the GPU (in terms of time per frame):

    https://github.com/setchi/Unity-ShaderSketches
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Shaders do indeed run entirely on the GPU. My question is how are you determining the GPU vs CPU "cost"? By default Unity shows "Main thread" and "Render thread" in the Game view's Stats window, and "CPU Usage" and "Rendering" in the profiler.

    Those are all CPU related. None of those show anything related to the GPU at all.

    Both the Rendering area in the profiler and the Rendering thread in the stats window is the CPU thread that's issuing rendering related commands to the graphics API (which is in turn issuing commands to the GPU). In the profiler the Rendering is a subcategory of what's already being shown in the CPU Usage graph at the top. However what you might see is the CPU Usage show a massive frame time while seemingly doing nothing. If you look at the CPU Usage breakdown to see what the most expensive item on the list is, you'll likely see something like "Gfx.WaitForPresent".

    Gfx.WaitForPresent is the GPU telling the CPU it's not done yet with the last frame and to stop sending more render commands. So the main CPU thread is stalling itself waiting for the GPU to finishing. It's not doing any actual work, even though that's what it looks like on first glance.

    You can enable actual GPU profiling in the editor by clicking on the Profiler Modules drop down in the top left of the Profiler window and enabling the GPU module. That'll let you see the actual GPU render times.
     
  3. april_4_short

    april_4_short

    Joined:
    Jul 19, 2021
    Posts:
    489
    Firstly, infinite thanks. This the kind of baseline consideration and conceptual insight I desperately needed, and was failing to piece together from dozens of videos, articles, documentation etc. You've made jigsaw pieces that were scattered all over the floor form a picture.

    A debt of gratitude is owed!

    On how I ascertained the CPU was getting a bit of a flogging: Heat on the CPU sinks, my fingers and the fans knew about it, and I have some monitoring software that checks various CPU temps for rendering offline 3D content, the Activity Monitor showed high CPU usage for Unity (all cores getting flogged) and the panel in the game view.

    You've changed my view on that CPU vs GPU number in the panel view...

    I know the Gfx.WaitForPresent you're talking about, I can get that anytime I go beserk with particles. But that's not what's bogging down the CPU.

    The odd thing is that performance doesn't slow down until the Macrapple Macrippling heat precautions kick in.

    Maybe this is all happening because I'm using an old 2018LTS to experiment with shaders, maybe this old version has something odd going on.

    Am using this old version because all the shader stuff online is old, plus it relaunches way faster than modern Unity, and just feels lighter and funner to experiment in that any of the new stuff.

    On the above, I've never managed to get this (admittedly, a year or so ago) to work in any meaningful way on a Mac, or for builds sent to iOS devices. Has this changed to the point where it's doing something for Mac/Apple users?
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    No idea if there's a way to make Unity's GPU profiling work for Mac. I believe the "solution" is to use XCode's profiling tools instead of Unity's, but I can't help you with that at all since I've never done Mac dev.

    The other issue you might be having is, assuming you're on a Macbook of some kind, and especially on iOS devices, is the total thermal output of the device is going to be limited, and GPUs put out a lot of heat. If you have a GPU heavy process going on, the amount of power being drawn & heat being produced by the GPU can cause the CPU to underclock significantly. All modern CPUs (and GPUs) will automatically underclock themselves when not in use or when hitting thermal limits. It's not unusual to see CPUs that are advertised as 3+ Ghz drop to sub 1Ghz clock rates or lower in situations of extreme thermal conditions.

    The other issue is if you have an older Intel based Macbook with no discrete GPU, or for whatever reason the editor is running on the integrated GPU instead of the discrete GPU, there are a lot of GPU features Intel implements in software on the CPU! This can similarly lead to the CPU usage to spike heavily if a shader is using one of those features that they didn't actually built into the GPU. But for vertex fragment shaders you'd need to be on a quite old Macbook for that to be the issue. Like 10+ years old at this point.
     
    lilacsky824 and april_4_short like this.
  5. april_4_short

    april_4_short

    Joined:
    Jul 19, 2021
    Posts:
    489
    Found an interesting oddity.

    If Unity (2018.LTS) is running in OpenGL 4.1 (which this old version seems to default to, sometimes...), then the CPU usage is much less, when running fancy shader experiments, than in Metal.

    And the whole computer likes it more, stays cooler longer.

    This might be different on later versions and newer Macs. Am experimenting on an old one with Nvidia GPU.
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Metal on desktop is an odd beast. I suspect there are some layers of effectively emulation or at least translation that has to happen to for Metal to render on most desktop GPUs. That likely explains the additional CPU usage.

    Those older Nvidia GPUs especially wouldn't fully support Metal. The last Nvidia GPUs in a Macbook Pro was the Nvidia GT 750M which isn't even fully Direct3D 11 compliant, let alone Metal compliant. It should be noted most of the 700 series GPUs are rebadged 600 series (Kepler) GPUs from 2012. Even many of the 2014-2016 800M & 900M series GPUs are effectively rebadged 600 series (Kepler) or even 500 series (Fermi) GPUs! There's a period of about 4 years there where Nvidia was so far ahead of AMD that they didn't meaningfully improve their GPUs abilities in terms of abilities, and most the top end GPUs were basically running 2-3 year old GPU architectures.

    AFAIK the only GPUs that fully and natively support Metal are recent ones made by Apple themselves, like those in their mobile devices and the M1 laptops. I suspect there is at least some additional CPU overhead for Metal on recent AMD GPU power Macs as well.
     
    april_4_short likes this.
  7. april_4_short

    april_4_short

    Joined:
    Jul 19, 2021
    Posts:
    489
    Just tried on Vega and 560X equipped Macbook Pros.

    Both the same, OpenGL is about 10x more efficient than Metal. Arguably, in some brief moments... more like 100x more so.

    So I think you're absolutely right, there's some fudgery and emulation going on.

    Perhaps this has something to do with Unity not being at WWDC...