1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

RTSS Feature Idea: GPU Load-Based Framerate Limit (this would be a HUGE help to streamers)

Discussion in 'Rivatuner Statistics Server (RTSS) Forum' started by ShamelessCookie, Oct 16, 2018.

  1. ShamelessCookie

    ShamelessCookie New Member

    Messages:
    4
    Likes Received:
    1
    GPU:
    RTX 2080 Ti FE
    So, RTSS is commonly used by Twitch streamers running Windows 10, because (for reasons unknown to me) a 99-100% GPU load prevents the popular OBS capture software from being able to render a full 60fps scene (frames drop in OBS, even though in-game the frames are 100+). Just look at everyone having the issue: https://www.google.com/search?hl=en&q=o ... gh%2060fps

    This apparently wasn't an issue on Win7, but with Win10, the only way to prevent this is to limit framerate with something like RTSS to keep GPU load < 90% and thus able to have enough spare horsepower to render the scene in OBS that will be sent to the encoder. This isn't limited to OBS either, it's every screen capture technology that exists for Windows 10 (including things like NDI), EXCEPT hardware based capture cards.

    In general, this is fine (in fact, RTSS is amazing for this!), except it's also common for Twitch streamers to want to play the latest games on high refresh GSYNC monitors (144Hz+) at high framerates (especially competitive games). Even with the most powerful hardware (I have an 8700K and an RTX 2080 Ti), the latest games can fluctuate between 80-150fps depending on resolution, graphics settings, and what's happening on scene. That means that in order to make sure the GPU is NEVER above 90% (because anything above 90% drops frames in OBS), streamers have to cap framerates all the way down in the 60-70 range permanently for the whole game, even though they could be getting well beyond that the majority of time.

    As of right now, the only real way to solve this problem is with an expensive capture card and a dual-PC setup. The capture card will be able to take in the raw frames, even when they dip to 70-80, and will be able to capture a smooth 60 from that without a problem. The problem only occurs when you are trying to capture 60fps from a GPU that is running at > 90%.

    Enter my idea: A dynamic framerate cap set on-the-fly by RTSS based on GPU load... so when GPU load spikes over 85% for example, the framerate limit automatically drops in order to keep GPU usage down. This could be in addition to the traditional framerate limit that we use to eliminate tearing and such.

    So, an ideal setup could be, for a 144Hz GSYNC monitor:

    - Hard framerate limit of 140 (following BlurBusters guidelines)
    - GPU load-based limit of 85%

    I have no idea if this is possible, or if the hardware monitoring polling is fast enough to adjust and apply framerate limits before the GPU spikes so high.

    Any thoughts? I know this would be a HUGELY popular feature for streamers, because they won't need a capture card, and will still be able to enjoy high framerates on their expensive video cards and monitors.

    Thanks!
     
  2. CaptaPraelium

    CaptaPraelium Master Guru

    Messages:
    229
    Likes Received:
    62
    GPU:
    1070
    TL;DR
    Limit capture framerate in OBS. (Rightclick game capture source, Click Properties, tick 'limit capture framerate')
    Disable GameDVR/Game Mode/FullScreen Optimisations (reg hacks/group policies etc)
    Disable overlays and GPU acceleration in other apps (eg steam/origin, browser, discord etc.)
    Enjoy.


    Why this works:
    This is mostly specific to OBS, it doesn't effect all other applications and is independent of issues with capturing. It occurs because (unlike other apps) OBS performs compositing of the scene and uses the GPU for this, so it is competing with other apps for GPU resources.

    By default, OBS captures ALL of your frames, even if you're recording/streaming at 60 if you're playing at 140 it's capturing 140. This places a not-insignificant load on the GPU. By limiting the capture framerate, OBS will only capture frames at the canvas rate (Settings...Video tab), thus reducing its load on the GPU (and CPU and RAM and PCIe buss etc etc)

    By default, windows 10 gives priority to the game (Game Mode/fullscreen optimisation) thus leaving insufficient resources for OBS to do its work in a timely fashion, and OBS dropping frames. When you disable these options that optimise the system for playing games (at the expense of being suboptimal for other background apps like say, OBS) they get equal priority. If your GPU utilisation approaches 100%, this of course means that if you're not slowing down OBS (by using game mode etc) then you're slowing down the game, after all, the GPU's resources are not infinite... but should not result in dropped frames (unless you are unable to maintain a framerate that matches or exceeds your canvas framerate which is a whole other unrelated problem.)

    By default, many applications such as Discord or your browser, will use your GPU to accelerate certain actions such as rendering to screen or playing video.
    Also, by default, many games or game launchers use overlays as a matter of convenience. However, these things place an undesirable load on your GPU and these defaults do not match your use case.


    Why your limiter idea wouldn't:
    The problem with having a limiter which slows the game based on GPU utilisation in order to allow GPU headroom for OBS, is that the problem occurs because OBS utilising the GPU, so OBS will actually contribute to the GPU utilisation which is used as a measure by which to limit the game. This could maybe help if we were able to monitor the GPU usage of the game alone (as opposed to total GPU usage), but it's best to just configure your system according to your needs as above, and let the machine balance them out appropriately.

    On top of this is the fact that high GPU utilisation and high framerates in game do no necessarily coincide. In many cases, the lower framerates occur when the GPU is highly utilised (as in, there's a very complex scene and the GPU is loaded up so the framerate drops) so you'd be reducing the framerate when it's already low but uncapping the framerate when it's very high. Although sometimes, the high GPU utilisation would occur when framerates are high (because it's processing lots of frames so it's doing lots of work) so then you'd be limiting the framerate when it's high but not when it's low. Effectively, you'd be dropping the framerate after the problem has already occurred. The only way around this would be to configure it to leave a bunch of headroom, which is effectively wasting a chunk of your GPU. Better to just let the system schedule the work evenly.

    Sources: Microsoft documentation (for Game Mode and friends, and GPU queuing behaviour), OBS source code and developers advice (for behaviour and limiting capture rate), tested extensively (using tools from MS, AMD, Intel and Unwinder and some custom charting), because I had this problem too... now playing 163FPS capped GSync and recording and streaming simultaneously in OBS with no dropped frames.

    HTH
     
  3. ShamelessCookie

    ShamelessCookie New Member

    Messages:
    4
    Likes Received:
    1
    GPU:
    RTX 2080 Ti FE
    Limit capture framerate causes OBS to only capture every other frame, which means that if you are capturing 60fps then any time you dip below 120fps in game you will dip below 60fps in OBS. This is confirmed by using a tool such as trdrop to analyze actual frames and you can see frames drop WELL below 60fps, ruining the smoothness of the recording, even though you are at over 100fps in game.

    what you're describing only works in games where you are constantly 120+fps. Many streamers do this if they play only in 1920x1080, or play simple games.... but trying to play an extremely demanding modern game at max settings, at a native resolution of e.g. 4K or ultrawide 3440x1440 and there's just no way to prevent the game from going below 120 fps.... which means Limit Capture Framerate ruins your smoothness by dropping you below 60.
     
    Last edited: Oct 17, 2018
  4. CaptaPraelium

    CaptaPraelium Master Guru

    Messages:
    229
    Likes Received:
    62
    GPU:
    1070
    If you're having trouble maintaining a high FPS feel free to skip this. The other advice still applies. Try it.
     

  5. CaptaPraelium

    CaptaPraelium Master Guru

    Messages:
    229
    Likes Received:
    62
    GPU:
    1070
    Checked the source code on this one. Are you super sure? I am a bit busy so maybe I've misread it but.......

    static inline void reset_frame_interval(struct game_capture *gc)
    {
    struct obs_video_info ovi;
    uint64_t interval = 0;

    if (obs_get_video_info(&ovi)) {
    interval = ovi.fps_den * 1000000000ULL / ovi.fps_num;

    /* Always limit capture framerate to some extent. If a game
    * running at 900 FPS is being captured without some sort of
    * limited capture interval, it will dramatically reduce
    * performance. */
    if (!gc->config.limit_framerate)
    interval /= 2;
    }

    gc->global_hook_info->frame_interval = interval;
    }


    Note the bang (if (!gc->config.limit_framerate)). It limits by half by default, if you don't tick the box (ie quote "Always limit capture framerate to some extent.")
    It limits to the canvas rate if you tick the box - which is what the dev told me... I just took his word for it but now that you've got me checking, it seems accurate. But like I said, I rushed this.


    Funny, we found a bug. There's an opportunity for an interval of 0 to be set, there.
     
    Last edited: Oct 17, 2018
  6. ShamelessCookie

    ShamelessCookie New Member

    Messages:
    4
    Likes Received:
    1
    GPU:
    RTX 2080 Ti FE
    Here's more evidence that the problem is GPU load, not "Limit Capture Framerate""

    OBS 64-bit 22.0.2
    Game Capture
    Canvas Resolution: 1920x800
    Scaled Resolution: 1920x800
    Downscale Filter: Bilinear
    Capture Framerate: 60
    i7 8700k
    RTX 2080 Ti
    3440x1440 (Single Display) GSYNC ON
    Windows 10 1809
    nVidia Drivers 416.34
    Vanishing of Ethan Carter Redux
    Exclusive Full Screen (Not Windowed)
    Game Bar Disabled
    ShadowPlay Instant Replay Disabled
    RTSS Scanline Sync ENABLED (120Hz refresh)

    "Limit Capture Framerate" Disabled



    • 2160p: GPU load: 99%, In-game FPS: 66, Captured FPS: 20
    • 1440p: GPU load: 99%, In-game FPS: 114, Captured FPS: 30
    • 1224p: GPU load: 95%, In-game FPS: 120, Captured FPS: 40
    • 1008p: GPU load: 79%, In-game FPS: 120, Captured FPS: 60
    [​IMG]


    "Limit Capture Framerate" enabled:


    • 2160p: GPU load: 99%, In-game FPS: 66, Captured FPS: 16
    • 1440p: GPU load: 99%, In-game FPS: 114, Captured FPS: 20
    • 1224p: GPU load: 95%, In-game FPS: 120, Captured FPS: 40
    • 1008p: GPU load: 79%, In-game FPS: 120, Captured FPS: 60
    [​IMG]
     
    Last edited: Oct 17, 2018
  7. CaptaPraelium

    CaptaPraelium Master Guru

    Messages:
    229
    Likes Received:
    62
    GPU:
    1070
    You seem to have misunderstood my posts. I don't know how I can better explain it to you. Good luck.
     
  8. mdrejhon

    mdrejhon Member Guru

    Messages:
    103
    Likes Received:
    60
    GPU:
    4 Flux Capacitors in SLI
    Chief Blur Buster here.

    Maybe I can help because I have an understanding of the problem, and what modifications are needed to RTSS to help a lot of streamers. I was the person who suggested to Unwinder to add the Scanline sync feature.

    What I believe that ShamelessCookie is asking for is a special feature in RTSS to automatically prevent GPU load from going above 90% (or a predefined threshold trigger).

    Basically when this proposed modified RTSS mode is enabled -- if a frametime takes 18.5ms -- RTSS should forces a mandatory 1.85ms CPU-busywait sleep until the next frame render. Basically if framerate is maxing out 50fps at 99% GPU, the mandatory ~10% autosleep would result in an approximately 9/10ths of 50fps = ~45fps. Basically, mandatory sleeps that are percentage-proportional to the previous frame rendering time. This can help GPU load to stay below a threshold.

    This plummets the GPU load, while increasing CPU load a little (because of precision busywait loop on CPU -- but Unwinder is also using intentional busywaits for scan line sync due to microsecond accuracy requirements)

    This new RTSS mode would probably be relatively simple to implement as (A) a configuration-file-only change specific to streamers and (B) take only a few lines of code.

    This could be trialled in a beta-only copy of RTSS, to prove/disprove whether this is a massive problem-solver -- for streamers playing games -- playing games that fluctuate massively in frametimes -- causing those GPUload-spikes above ~90% to cause dropped streamable frames.

    This could be implemented as a blocking sleep before returning from Present(). Certainly this will add a tiny bit of lag (most of the time, sub-millisecond lag for 100fps+ operation). But successful streaming at 110fps is superior to heavily framedropped streaming at 120fps.

    Games often vary hugely from 40fps thru 200fps, so anytime there's a big shooting fight and there's a temporary GPU load spike (99%), this cause framedropping during streaming. By forcing a blocking CPU busywait before returning from a Present() or glutSwapBuffers() that's proportional to the previous frametime, the streaming features notices the GPU is idling and grabs the GPU to process the frame.

    Essentially.... You trade a bit of lag (sub-millisecond), a bit of lower framerate (e.g. 1% or 5% or such), in exchange for perfect streaming with zero framedrops -- no matter how much your game framerate fluctuates.

    And would perform SO much better than other drastic solutions (like capping to the bottom dip, e.g. capping at 40fps because your framerate fluctuates 40fps-200fps....UGH.... :D ).

    As you can see, this Hail Mary solution is what they're doing today -- making huge sacrifices like this by being forced to cap just below the bottom of your framerate valleys!. So even (figuratively speaking, from the streamer's perspective) -- Compared to a massive hobbling of your framerate, even just a mere optional 1ms busywait ends up being a massive upgrade almost akin to buying 3 generations newer GPU -- For those streamers who do not want dropped frames.

    Viewers of streams complain of stuttery streams during the "heated moments" of firefights that they visited the stream for. That's what happens; GPU load spikes, stream compressor fails to catch all frames, and the exciting moments are not enjoyed by stream viewers.

    Essentially, a defacto GPU-load-adapting framerate cap -- as a very simple autosleeper that's proportional to the previous frametime.

    Even if the streamer is only transmitting 60 frames per second when playing at 100fps-200fps. Stream-framedrops are still happening in Windows 10 that never happened in Windows 7

    Alternatively -- even simpler idea -- it could be a configurable fixed busywait (e.g. 0.5ms always) rather than an adaptive busywait. Since the stream renderer probably has a fixed threshold, and only needs a fixed time per frame to compress it. This is even simpler mod to RTSS). So you'd have negligible framerate decrease (0.5ms increase to frametimes), but sufficient microscopic CPU busywait to cause the GPU to focus on stream compression task. Obviously, 0.5 would be a value, but tweakable until the streaming worked flawlessly. (e.g. 0.25ms, or 1ms, 2ms or whatever busywait is required to force GPU idle time between frame renders).

    Other techniques (other than busywait) can also be used, if more appropriate (e.g. dynamically free-floating framerate cap that that avoids GPU from exceeding a percentage threshold). I only simply suggest initially trying the busywait technique because it's quick-and-dirty minor-code-change test to at least validate one RTSS beta on whether it helps streamers...

    Possible secondary purposes: This advanced-user-only or betas-only INI config feature can in theory be a a useful developer engineering/debugging feature, because anecdotally, some games suddenly gain mysterious input lag whenever GPU-bottlenecked (even when not using VSYNC ON). Experimenting with this forced GPU-load-capping feature can, in theory, help advanced tweakers debug whether the game has a strange block occuring on GPU load (despite running in uncapped modes such as VSYNC OFF or Fast Sync, etc).

    I know Unwinder is reluctant to add new INI options because newbies copy and paste them all the time without understanding. You can even name the option "AddLagPerFrame=0.5" (fixed ms) or, say "AddLagPerFrame=10%" (perc) to discourage everyday users from randomly copy and pasting it into their RTSS INI files. To reduce/prevent those newbie-complainer side effects that go with advanced options. Twitch streamers will be able to study this option and find it's a lesser-of-poison to add 0.5ms lag per frame (or calibrated value) to get perfect frame-drop-free streaming, while most everyday competitive players will just say "ugh, no lag, won't use it".

    Yes, this is kind of a workaround for a Windows 10 defect to streamers, but it would be a huge boon to many high performance streamers. Yes, I know it's hairpulling; I know, I know, I've been there.

    This just sounds so deceptively simple for an INI-only option -- so minor a programming modification -- probably mainly consisting of one-line to three-line mods in approximately three places -- that can be trialled in a beta-only RTSS -- yet appears potentially to a huge windfall problem-solve for high-performance twitch streamers.

    Certainly -- with busy people -- it's up to the key RTSS authors (@Unwinder) but hopefully I've explained the purpose of this better?
     
    Last edited: Oct 17, 2018
  9. Unwinder

    Unwinder Moderator Staff Member

    Messages:
    14,394
    Likes Received:
    1,417
    Sorry, I'm afraid we're pushing framerate limiting functionality a bit too far. Even without that I'm already working in 16 work hours per day schedule during the last few weeks. I cannot invest more additional time in experiments with framerate limiting, sorry
     
  10. mdrejhon

    mdrejhon Member Guru

    Messages:
    103
    Likes Received:
    60
    GPU:
    4 Flux Capacitors in SLI
    Totally understand.

    Ideally, since it's a problem that appeared in Windows 10 that did not occur in Windows 7 -- it is indeed probably Microsoft's responsibility (along with GPU vendors) to provide a solution or tweak for the OBS use case. To fix this obscure problem. Still, we know how things move slowly in this department -- and if your time frees up in a few months -- or if some good sponsor pays you a mint (if good $ since y'know, eSports = $$$$ = possibly high dollar per line of code for this, so maybe recruit a sponsor).

    But let's bang my head on a Microsoft desk instead...for now ;)
     
    Last edited: Oct 17, 2018

  11. RealNC

    RealNC Ancient Guru

    Messages:
    3,082
    Likes Received:
    1,317
    GPU:
    EVGA GTX 980 Ti FTW
    @Unwinder

    Is the RTSS beta build that still had the failed "ThrottleTime" experiment still available? I think it was 7.2.0 Beta 1. It was an experiment to test input lag reduction, which turned out didn't help, but it might solve this issue, since ThrottleTime could be used to keep the GPU from getting maxed out.

    If that beta build is still available for download somewhere, it might be worth testing by streamers.
     
    Last edited: Oct 17, 2018
  12. Unwinder

    Unwinder Moderator Staff Member

    Messages:
    14,394
    Likes Received:
    1,417
    It is still available in current betas
     
  13. RealNC

    RealNC Ancient Guru

    Messages:
    3,082
    Likes Received:
    1,317
    GPU:
    EVGA GTX 980 Ti FTW
    Ah, OK.

    @ShamelessCookie
    Add ThrottleTime=3000 in the [Framerate] section of the profile file, and see if that helps. This is the amount of microseconds to wait if the game isn't able to reach the FPS cap. (3000us is 3ms). In theory, if this value is equal or a bit larger than the amount of time OBS needs to use the GPU each frame, there should be less frame drops.

    In theory...
     
  14. Smough

    Smough Member Guru

    Messages:
    160
    Likes Received:
    21
    GPU:
    GTX 1060 3GB
    Does this work with the latest beta version of RTSS?
     
  15. RealNC

    RealNC Ancient Guru

    Messages:
    3,082
    Likes Received:
    1,317
    GPU:
    EVGA GTX 980 Ti FTW
    Unwinder said that it's still in the latest beta. It was an experiment in 7.2.0 beta 1 to reduce input lag with some games when GPU gets to 100%, but it turned out it didn't help. But it was not removed and it's still there in the latest beta.

    Whether it actually helps or not is another question, but it's worth trying. You just need to find the RTSS install folder, and in the "Profiles" folder is a file called "Global" (no file extension.) Open that in a text editor, find the "[Framerate]" section, and just add a new line just below it:

    ThrottleTime=3000

    You need to restart RTSS every time you change the value. If you want this to only apply to a specific game, then you need to edit the profile file for that game instead of the "Global" file.
     

  16. ShamelessCookie

    ShamelessCookie New Member

    Messages:
    4
    Likes Received:
    1
    GPU:
    RTX 2080 Ti FE
    Thanks for the tips! I tried playing around with the "ThrottleTime" value and have had some interesting results.

    With the following settings:

    Code:
    [Framerate]
    ThrottleTime=2000
    Limit=120
    LimitDenominator=1
    LimitTime=0
    SyncScanline0=1
    SyncScanline1=0
    SyncPeriods=0
    SyncTimeout=1
    
    And playing a game that can sometimes (but not always) get 120fps, I observe the correct desired behavior of a 120fps limit under ideal circumstances, and at 96-97fps limit (8.33ms + 2.00ms) when the game can't maintain a solid 120fps.... however, this only happens when the game is OUT of focus! Meaning, the game is running in Windowed Fullscreen with a different application in focus. As soon as I bring focus to the game, the ThrottleTime is applied permanently, and the cap is forever 97fps, never returning to 120 until I Alt+Tab to a different application.

    Note that if I try to use "ThrottleTime" without also enabling "SyncScanline", the frametimes oscillate very rapidly between throttled and non-throttled. The only way to get a consistent flat frametime graph is to also enable SyncScaline (which is fine, because I enjoy the flat frametimes).
     
    Smough likes this.
  17. Smough

    Smough Member Guru

    Messages:
    160
    Likes Received:
    21
    GPU:
    GTX 1060 3GB
    That's very interesting, I am gonna try some of those things to see the results.
     
  18. Can Çeralp

    Can Çeralp Member

    Messages:
    22
    Likes Received:
    6
    GPU:
    Rx 480 8Gb
    It works! I mean, it used to work. It doesn't with the new RTSS 7.2.2..

    What I have done is;
    -Close everything (including RTSS).

    -Open Task Manager and see GPU usage graph. For me, it is 3% at idle.

    -Start a display capture with OBS. And now look at the GPU usage. For me, it is 11%.
    The difference is 8%. That means, I need to reserve roughly 10% of my GPU power for OBS and would be good to go.

    -Now, I want to cap my game FPS and also record at 60FPS. This means, 60 FPS power potential + 10% reservation would be my bottom limit. Think it like that: if my GPU is capable of rendering a scene at 120 FPS, then no problem for a 60 FPS cap. 80FPS potential, no problem. 70, again, no problem. 66 FPS, that works, too. Because 66 = 60 + 10% reservation.

    So what is the reservation time for 10% of 60 FPS? 1.667ms.

    -Now add ThrottleTime=1667 to the global file.

    Now your in-game FPS and OBS FPS are tied. As long as your GPU can handle 60+ FPS, both in-game and OBS will have 60 smooth FPS. If the game dips below 60, say 55, OBS will record at 55.

    TL, DR; ThrottleTime was the only working band-aid that OBS needed with Windows 10 GPU priority problems. However it stopped working on the new version of RTSS.
     
  19. Andy_K

    Andy_K Master Guru

    Messages:
    427
    Likes Received:
    35
    GPU:
    MSI GTX 960 OC
    @Can Çeralp
    You cannot calculate (idle+recording load%) - idle load% = load% to leave open for recording under heavy load.
    Video capturing does not work this way on GPU load.

    First of all, encoding nowadays (h.264 and h.265) usually uses the video encoding engine, it's a separate chip on the graphics card and not the gpu. So the gpu load is irrelevant to the encoding itself.

    Second the whole rendered frame has to be pushed to the VCE, therefor the render target has to be flushed to ensure everything is rendered before VCE gets the image to encode. This impacts the performance a little bit and a bit more if asynchronous compute is used as the flushing negates most of the performance benefits of this technique.
     
  20. Can Çeralp

    Can Çeralp Member

    Messages:
    22
    Likes Received:
    6
    GPU:
    Rx 480 8Gb
    That formula I made up, is for OBS only. For reasons beyond my understanding, OBS doesn't work like ReLive or Shadowplay. It asks the GPU to make a render copy of the scene to be encoded. Then the encoder chip takes over. That 8% is for GPU rendering a copy of the screen (or window) to the VCE.

    I believe that's why it helped to set a ThrottleTime to the game for leaving a rendering room for the GPU. I did the same for CPU, by leaving only one core (of my i5 6500) to OBS and giving other 3 to the game from Task Manager's affinity feature. By doing this; OBS reserved 25% CPU, 10% GPU for itself and never skips/drops frames. Normally, when my in-game FPS dropped below 60 (which is my RTSS cap) because of a GPU 100% load, OBS would record at 1-2FPS. With that formula and ThrottleTime, it was taking whatever the game was giving. Game = 45, then OBS = 45, game is 60 = OB = 60.
     

Share This Page