Steady_Clock skipping between updates in main game loop (c++)











up vote
7
down vote

favorite












In the process of trying to work out a solid game loop in SFML I came across this issue which I can't seem to figure out. I was able to strip out all of the SFML code and still see the issue with clock() in time.h. Then I went further and still see the problem using std::chrono::steady_clock.



The issue:
Somewhat consistently I see skips in the amount of work able to be done between updates. Each update should take 1/60th of a second, and the rest of the time is spend in Draw() getting as much drawing done as possible.
Sometimes the amount of draws drops to 0 or 1 for no obvious reason. This bubbles up to the actual application in the form of noticeable stuttering. Other than the "skips" the number of draws done is very consistent.



Here is an image (notice the jump in update time and drop in draws):
Console output of the issue



Some code:



#include <iostream>
#include <time.h>
#include <chrono>

using namespace std;
using namespace std::chrono;

void Draw()
{
//for (int i = 0; i < 1000000; i++);
}

int main()
{
steady_clock::time_point update_time;
steady_clock::time_point update_next;
int update_rate = 16666666; // 60 times a second (nanosecs)
int updates;
int max_updates = 5;
int draws = 0;
update_next = steady_clock::now();

while (true)
{
updates = 0;
update_time = steady_clock::now();
while (duration_cast<nanoseconds>(update_time - update_next) > nanoseconds(update_rate) && updates++ < max_updates)
{
if (draws <= 1) {
cout << "!!!!!!!!!!!!!ERROR!!!!!!!!!!!!!" << endl;
}
cout << "UPDATE - ";
cout << "Draws: " << draws
<< " - UT - UN: " << duration_cast<nanoseconds>(update_time - update_next).count()
<< endl;

draws = 0;
update_next += nanoseconds(update_rate);
}
draws++;
Draw();
}

return 0;
}



  • Perhaps there is something I don't understand about typical applications? Does Windows need to hijack CPU cycles every so often?

  • I have seen this problem with steady_clock, clock, and in a fleshed out SFML app where work is done during Update and Draw

  • I assume SFML clock probably uses time.h clock

  • From my testing the max_updates checks have nothing to do with this issue (I don't think they are causing the problem)


The fact that I have seen this with a few different timers leads me to believe there is something wrong with my implementation or my system. This example was run in VS but I have seen it also in a standalone release exe. Playing with the update rate or the amount of work done in draw may help it show up for you.



Any help or insight you can provide would be excellent, thanks!





Edit
After testing out my background processes I noticed a strange correlation. This skipping issue only occurs when the Spotify web player is open in chrome and occurs once a second or so...
If anyone has any ideas on that I'm open to them...



I found this post which may be related:
https://community.spotify.com/t5/Other-Partners-Web-Player-etc/Web-Player-on-Chrome-causes-lag-stutter/td-p/4587103










share|improve this question









New contributor




S. Turnage is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
























    up vote
    7
    down vote

    favorite












    In the process of trying to work out a solid game loop in SFML I came across this issue which I can't seem to figure out. I was able to strip out all of the SFML code and still see the issue with clock() in time.h. Then I went further and still see the problem using std::chrono::steady_clock.



    The issue:
    Somewhat consistently I see skips in the amount of work able to be done between updates. Each update should take 1/60th of a second, and the rest of the time is spend in Draw() getting as much drawing done as possible.
    Sometimes the amount of draws drops to 0 or 1 for no obvious reason. This bubbles up to the actual application in the form of noticeable stuttering. Other than the "skips" the number of draws done is very consistent.



    Here is an image (notice the jump in update time and drop in draws):
    Console output of the issue



    Some code:



    #include <iostream>
    #include <time.h>
    #include <chrono>

    using namespace std;
    using namespace std::chrono;

    void Draw()
    {
    //for (int i = 0; i < 1000000; i++);
    }

    int main()
    {
    steady_clock::time_point update_time;
    steady_clock::time_point update_next;
    int update_rate = 16666666; // 60 times a second (nanosecs)
    int updates;
    int max_updates = 5;
    int draws = 0;
    update_next = steady_clock::now();

    while (true)
    {
    updates = 0;
    update_time = steady_clock::now();
    while (duration_cast<nanoseconds>(update_time - update_next) > nanoseconds(update_rate) && updates++ < max_updates)
    {
    if (draws <= 1) {
    cout << "!!!!!!!!!!!!!ERROR!!!!!!!!!!!!!" << endl;
    }
    cout << "UPDATE - ";
    cout << "Draws: " << draws
    << " - UT - UN: " << duration_cast<nanoseconds>(update_time - update_next).count()
    << endl;

    draws = 0;
    update_next += nanoseconds(update_rate);
    }
    draws++;
    Draw();
    }

    return 0;
    }



    • Perhaps there is something I don't understand about typical applications? Does Windows need to hijack CPU cycles every so often?

    • I have seen this problem with steady_clock, clock, and in a fleshed out SFML app where work is done during Update and Draw

    • I assume SFML clock probably uses time.h clock

    • From my testing the max_updates checks have nothing to do with this issue (I don't think they are causing the problem)


    The fact that I have seen this with a few different timers leads me to believe there is something wrong with my implementation or my system. This example was run in VS but I have seen it also in a standalone release exe. Playing with the update rate or the amount of work done in draw may help it show up for you.



    Any help or insight you can provide would be excellent, thanks!





    Edit
    After testing out my background processes I noticed a strange correlation. This skipping issue only occurs when the Spotify web player is open in chrome and occurs once a second or so...
    If anyone has any ideas on that I'm open to them...



    I found this post which may be related:
    https://community.spotify.com/t5/Other-Partners-Web-Player-etc/Web-Player-on-Chrome-causes-lag-stutter/td-p/4587103










    share|improve this question









    New contributor




    S. Turnage is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






















      up vote
      7
      down vote

      favorite









      up vote
      7
      down vote

      favorite











      In the process of trying to work out a solid game loop in SFML I came across this issue which I can't seem to figure out. I was able to strip out all of the SFML code and still see the issue with clock() in time.h. Then I went further and still see the problem using std::chrono::steady_clock.



      The issue:
      Somewhat consistently I see skips in the amount of work able to be done between updates. Each update should take 1/60th of a second, and the rest of the time is spend in Draw() getting as much drawing done as possible.
      Sometimes the amount of draws drops to 0 or 1 for no obvious reason. This bubbles up to the actual application in the form of noticeable stuttering. Other than the "skips" the number of draws done is very consistent.



      Here is an image (notice the jump in update time and drop in draws):
      Console output of the issue



      Some code:



      #include <iostream>
      #include <time.h>
      #include <chrono>

      using namespace std;
      using namespace std::chrono;

      void Draw()
      {
      //for (int i = 0; i < 1000000; i++);
      }

      int main()
      {
      steady_clock::time_point update_time;
      steady_clock::time_point update_next;
      int update_rate = 16666666; // 60 times a second (nanosecs)
      int updates;
      int max_updates = 5;
      int draws = 0;
      update_next = steady_clock::now();

      while (true)
      {
      updates = 0;
      update_time = steady_clock::now();
      while (duration_cast<nanoseconds>(update_time - update_next) > nanoseconds(update_rate) && updates++ < max_updates)
      {
      if (draws <= 1) {
      cout << "!!!!!!!!!!!!!ERROR!!!!!!!!!!!!!" << endl;
      }
      cout << "UPDATE - ";
      cout << "Draws: " << draws
      << " - UT - UN: " << duration_cast<nanoseconds>(update_time - update_next).count()
      << endl;

      draws = 0;
      update_next += nanoseconds(update_rate);
      }
      draws++;
      Draw();
      }

      return 0;
      }



      • Perhaps there is something I don't understand about typical applications? Does Windows need to hijack CPU cycles every so often?

      • I have seen this problem with steady_clock, clock, and in a fleshed out SFML app where work is done during Update and Draw

      • I assume SFML clock probably uses time.h clock

      • From my testing the max_updates checks have nothing to do with this issue (I don't think they are causing the problem)


      The fact that I have seen this with a few different timers leads me to believe there is something wrong with my implementation or my system. This example was run in VS but I have seen it also in a standalone release exe. Playing with the update rate or the amount of work done in draw may help it show up for you.



      Any help or insight you can provide would be excellent, thanks!





      Edit
      After testing out my background processes I noticed a strange correlation. This skipping issue only occurs when the Spotify web player is open in chrome and occurs once a second or so...
      If anyone has any ideas on that I'm open to them...



      I found this post which may be related:
      https://community.spotify.com/t5/Other-Partners-Web-Player-etc/Web-Player-on-Chrome-causes-lag-stutter/td-p/4587103










      share|improve this question









      New contributor




      S. Turnage is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      In the process of trying to work out a solid game loop in SFML I came across this issue which I can't seem to figure out. I was able to strip out all of the SFML code and still see the issue with clock() in time.h. Then I went further and still see the problem using std::chrono::steady_clock.



      The issue:
      Somewhat consistently I see skips in the amount of work able to be done between updates. Each update should take 1/60th of a second, and the rest of the time is spend in Draw() getting as much drawing done as possible.
      Sometimes the amount of draws drops to 0 or 1 for no obvious reason. This bubbles up to the actual application in the form of noticeable stuttering. Other than the "skips" the number of draws done is very consistent.



      Here is an image (notice the jump in update time and drop in draws):
      Console output of the issue



      Some code:



      #include <iostream>
      #include <time.h>
      #include <chrono>

      using namespace std;
      using namespace std::chrono;

      void Draw()
      {
      //for (int i = 0; i < 1000000; i++);
      }

      int main()
      {
      steady_clock::time_point update_time;
      steady_clock::time_point update_next;
      int update_rate = 16666666; // 60 times a second (nanosecs)
      int updates;
      int max_updates = 5;
      int draws = 0;
      update_next = steady_clock::now();

      while (true)
      {
      updates = 0;
      update_time = steady_clock::now();
      while (duration_cast<nanoseconds>(update_time - update_next) > nanoseconds(update_rate) && updates++ < max_updates)
      {
      if (draws <= 1) {
      cout << "!!!!!!!!!!!!!ERROR!!!!!!!!!!!!!" << endl;
      }
      cout << "UPDATE - ";
      cout << "Draws: " << draws
      << " - UT - UN: " << duration_cast<nanoseconds>(update_time - update_next).count()
      << endl;

      draws = 0;
      update_next += nanoseconds(update_rate);
      }
      draws++;
      Draw();
      }

      return 0;
      }



      • Perhaps there is something I don't understand about typical applications? Does Windows need to hijack CPU cycles every so often?

      • I have seen this problem with steady_clock, clock, and in a fleshed out SFML app where work is done during Update and Draw

      • I assume SFML clock probably uses time.h clock

      • From my testing the max_updates checks have nothing to do with this issue (I don't think they are causing the problem)


      The fact that I have seen this with a few different timers leads me to believe there is something wrong with my implementation or my system. This example was run in VS but I have seen it also in a standalone release exe. Playing with the update rate or the amount of work done in draw may help it show up for you.



      Any help or insight you can provide would be excellent, thanks!





      Edit
      After testing out my background processes I noticed a strange correlation. This skipping issue only occurs when the Spotify web player is open in chrome and occurs once a second or so...
      If anyone has any ideas on that I'm open to them...



      I found this post which may be related:
      https://community.spotify.com/t5/Other-Partners-Web-Player-etc/Web-Player-on-Chrome-causes-lag-stutter/td-p/4587103







      c++ game-engine clock game-development game-loop






      share|improve this question









      New contributor




      S. Turnage is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question









      New contributor




      S. Turnage is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question








      edited 2 hours ago





















      New contributor




      S. Turnage is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 5 hours ago









      S. Turnage

      363




      363




      New contributor




      S. Turnage is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      S. Turnage is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      S. Turnage is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.
























          3 Answers
          3






          active

          oldest

          votes

















          up vote
          4
          down vote














          Perhaps there is something I don't understand about typical applications? Does Windows need to hijack CPU cycles every so often?




          Yes, absolutely. Windows is running a whole lot of processes all at once. Now your application comes along and executes what is essentially a busy spin-loop. At some point, the OS is likely to de-prioritize this for longer than you expect because it just looks like a long calculation, and the OS needs to give other processes a fair share of CPU time.



          In general you should not rely on your drawing routine being called an exact number of times per second, and your game's master clock should be able to cope with skipped frames. I'm not familiar with SFML so I can't comment on that.



          However, I do have experience with realtime audio (and video for that matter) running in loops that exceed 1000 updates per second. You can improve your game loop time share by setting the thread priority to THREAD_PRIORITY_HIGHEST or THREAD_PRIORITY_TIME_CRITICAL (see SetThreadPriority).



          For this to be effective you should also be a well-behaved application and periodically perform some kind of wait. Waiting allows the OS to do its necessary task-switching to service other processes (several of which will also be a high priority, and often higher than you will be able to force as a userspace application).



          The obvious place for a wait is prior to your next draw cycle. Rather than spinning on your timer with 100% core utilization, simply calculate how long you're prepared to wait and call std::this_thread::sleep_for. Remember that the only guarantee is the sleep will be for at least the amount you specify. It absolutely can and will be more than this. But I recommend you start there and do some experiments.






          share|improve this answer





















          • How effective is std::this_thread::yield for this sort of thing? EDIT: i.e. is spinning while calling std:this_thread::yield an effective way of reducing the possibility of oversleeping
            – James Picone
            4 hours ago








          • 1




            I don't have personal experience using that for this kind of thing. I'd say it's more suited to things like spin-locks and very short-duration timing spins. I would definitely not want to run a 60Hz game loop with a spin-wait + yield, especially not if I'd also upped the thread priority.
            – paddy
            4 hours ago






          • 1




            Right, so as you edited your comment, then yes that could be a performance tweak. Since the sleep_for can come out late, you can use a shorter sleep than you need, then use yield for tighter spin "sleeps" that pad out any undershooting. That's down to experimentation and black magic.
            – paddy
            4 hours ago












          • I tried both of these, adding a thread sleep for as long as 10ms on each update, and still see the problem :(
            – S. Turnage
            3 hours ago




















          up vote
          1
          down vote













          In addition to @paddy's answer I recommend you look into fixed timesteps. If that isn't worth the trouble of implementing then you should also note that SFML has Window.setFramerateLimit(). It's not very precise but most simple games don't need significant precision.






          share|improve this answer





















          • The fixed timesteps link is a good one, and what I used to come up with the code example. I also see the issue even when using SFMLs setFrameLimit. For some reason the clock is jumping a huge amount of time.
            – S. Turnage
            3 hours ago












          • Well the FrameLimit only keeps your loop from running too often on a fast cpu. It doesn't stop the framerate from dropping. What are you running in your background anyway? Could you try on a different machine?
            – bruglesco
            3 hours ago


















          up vote
          0
          down vote













          I've used spinning loop plus yield for 1 KHz control loops with good results, but expect some deadline miss (once in thousands cycles also long sleeping times).






          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });






            S. Turnage is a new contributor. Be nice, and check out our Code of Conduct.










            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53735418%2fsteady-clock-skipping-between-updates-in-main-game-loop-c%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            4
            down vote














            Perhaps there is something I don't understand about typical applications? Does Windows need to hijack CPU cycles every so often?




            Yes, absolutely. Windows is running a whole lot of processes all at once. Now your application comes along and executes what is essentially a busy spin-loop. At some point, the OS is likely to de-prioritize this for longer than you expect because it just looks like a long calculation, and the OS needs to give other processes a fair share of CPU time.



            In general you should not rely on your drawing routine being called an exact number of times per second, and your game's master clock should be able to cope with skipped frames. I'm not familiar with SFML so I can't comment on that.



            However, I do have experience with realtime audio (and video for that matter) running in loops that exceed 1000 updates per second. You can improve your game loop time share by setting the thread priority to THREAD_PRIORITY_HIGHEST or THREAD_PRIORITY_TIME_CRITICAL (see SetThreadPriority).



            For this to be effective you should also be a well-behaved application and periodically perform some kind of wait. Waiting allows the OS to do its necessary task-switching to service other processes (several of which will also be a high priority, and often higher than you will be able to force as a userspace application).



            The obvious place for a wait is prior to your next draw cycle. Rather than spinning on your timer with 100% core utilization, simply calculate how long you're prepared to wait and call std::this_thread::sleep_for. Remember that the only guarantee is the sleep will be for at least the amount you specify. It absolutely can and will be more than this. But I recommend you start there and do some experiments.






            share|improve this answer





















            • How effective is std::this_thread::yield for this sort of thing? EDIT: i.e. is spinning while calling std:this_thread::yield an effective way of reducing the possibility of oversleeping
              – James Picone
              4 hours ago








            • 1




              I don't have personal experience using that for this kind of thing. I'd say it's more suited to things like spin-locks and very short-duration timing spins. I would definitely not want to run a 60Hz game loop with a spin-wait + yield, especially not if I'd also upped the thread priority.
              – paddy
              4 hours ago






            • 1




              Right, so as you edited your comment, then yes that could be a performance tweak. Since the sleep_for can come out late, you can use a shorter sleep than you need, then use yield for tighter spin "sleeps" that pad out any undershooting. That's down to experimentation and black magic.
              – paddy
              4 hours ago












            • I tried both of these, adding a thread sleep for as long as 10ms on each update, and still see the problem :(
              – S. Turnage
              3 hours ago

















            up vote
            4
            down vote














            Perhaps there is something I don't understand about typical applications? Does Windows need to hijack CPU cycles every so often?




            Yes, absolutely. Windows is running a whole lot of processes all at once. Now your application comes along and executes what is essentially a busy spin-loop. At some point, the OS is likely to de-prioritize this for longer than you expect because it just looks like a long calculation, and the OS needs to give other processes a fair share of CPU time.



            In general you should not rely on your drawing routine being called an exact number of times per second, and your game's master clock should be able to cope with skipped frames. I'm not familiar with SFML so I can't comment on that.



            However, I do have experience with realtime audio (and video for that matter) running in loops that exceed 1000 updates per second. You can improve your game loop time share by setting the thread priority to THREAD_PRIORITY_HIGHEST or THREAD_PRIORITY_TIME_CRITICAL (see SetThreadPriority).



            For this to be effective you should also be a well-behaved application and periodically perform some kind of wait. Waiting allows the OS to do its necessary task-switching to service other processes (several of which will also be a high priority, and often higher than you will be able to force as a userspace application).



            The obvious place for a wait is prior to your next draw cycle. Rather than spinning on your timer with 100% core utilization, simply calculate how long you're prepared to wait and call std::this_thread::sleep_for. Remember that the only guarantee is the sleep will be for at least the amount you specify. It absolutely can and will be more than this. But I recommend you start there and do some experiments.






            share|improve this answer





















            • How effective is std::this_thread::yield for this sort of thing? EDIT: i.e. is spinning while calling std:this_thread::yield an effective way of reducing the possibility of oversleeping
              – James Picone
              4 hours ago








            • 1




              I don't have personal experience using that for this kind of thing. I'd say it's more suited to things like spin-locks and very short-duration timing spins. I would definitely not want to run a 60Hz game loop with a spin-wait + yield, especially not if I'd also upped the thread priority.
              – paddy
              4 hours ago






            • 1




              Right, so as you edited your comment, then yes that could be a performance tweak. Since the sleep_for can come out late, you can use a shorter sleep than you need, then use yield for tighter spin "sleeps" that pad out any undershooting. That's down to experimentation and black magic.
              – paddy
              4 hours ago












            • I tried both of these, adding a thread sleep for as long as 10ms on each update, and still see the problem :(
              – S. Turnage
              3 hours ago















            up vote
            4
            down vote










            up vote
            4
            down vote










            Perhaps there is something I don't understand about typical applications? Does Windows need to hijack CPU cycles every so often?




            Yes, absolutely. Windows is running a whole lot of processes all at once. Now your application comes along and executes what is essentially a busy spin-loop. At some point, the OS is likely to de-prioritize this for longer than you expect because it just looks like a long calculation, and the OS needs to give other processes a fair share of CPU time.



            In general you should not rely on your drawing routine being called an exact number of times per second, and your game's master clock should be able to cope with skipped frames. I'm not familiar with SFML so I can't comment on that.



            However, I do have experience with realtime audio (and video for that matter) running in loops that exceed 1000 updates per second. You can improve your game loop time share by setting the thread priority to THREAD_PRIORITY_HIGHEST or THREAD_PRIORITY_TIME_CRITICAL (see SetThreadPriority).



            For this to be effective you should also be a well-behaved application and periodically perform some kind of wait. Waiting allows the OS to do its necessary task-switching to service other processes (several of which will also be a high priority, and often higher than you will be able to force as a userspace application).



            The obvious place for a wait is prior to your next draw cycle. Rather than spinning on your timer with 100% core utilization, simply calculate how long you're prepared to wait and call std::this_thread::sleep_for. Remember that the only guarantee is the sleep will be for at least the amount you specify. It absolutely can and will be more than this. But I recommend you start there and do some experiments.






            share|improve this answer













            Perhaps there is something I don't understand about typical applications? Does Windows need to hijack CPU cycles every so often?




            Yes, absolutely. Windows is running a whole lot of processes all at once. Now your application comes along and executes what is essentially a busy spin-loop. At some point, the OS is likely to de-prioritize this for longer than you expect because it just looks like a long calculation, and the OS needs to give other processes a fair share of CPU time.



            In general you should not rely on your drawing routine being called an exact number of times per second, and your game's master clock should be able to cope with skipped frames. I'm not familiar with SFML so I can't comment on that.



            However, I do have experience with realtime audio (and video for that matter) running in loops that exceed 1000 updates per second. You can improve your game loop time share by setting the thread priority to THREAD_PRIORITY_HIGHEST or THREAD_PRIORITY_TIME_CRITICAL (see SetThreadPriority).



            For this to be effective you should also be a well-behaved application and periodically perform some kind of wait. Waiting allows the OS to do its necessary task-switching to service other processes (several of which will also be a high priority, and often higher than you will be able to force as a userspace application).



            The obvious place for a wait is prior to your next draw cycle. Rather than spinning on your timer with 100% core utilization, simply calculate how long you're prepared to wait and call std::this_thread::sleep_for. Remember that the only guarantee is the sleep will be for at least the amount you specify. It absolutely can and will be more than this. But I recommend you start there and do some experiments.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 4 hours ago









            paddy

            42.4k53076




            42.4k53076












            • How effective is std::this_thread::yield for this sort of thing? EDIT: i.e. is spinning while calling std:this_thread::yield an effective way of reducing the possibility of oversleeping
              – James Picone
              4 hours ago








            • 1




              I don't have personal experience using that for this kind of thing. I'd say it's more suited to things like spin-locks and very short-duration timing spins. I would definitely not want to run a 60Hz game loop with a spin-wait + yield, especially not if I'd also upped the thread priority.
              – paddy
              4 hours ago






            • 1




              Right, so as you edited your comment, then yes that could be a performance tweak. Since the sleep_for can come out late, you can use a shorter sleep than you need, then use yield for tighter spin "sleeps" that pad out any undershooting. That's down to experimentation and black magic.
              – paddy
              4 hours ago












            • I tried both of these, adding a thread sleep for as long as 10ms on each update, and still see the problem :(
              – S. Turnage
              3 hours ago




















            • How effective is std::this_thread::yield for this sort of thing? EDIT: i.e. is spinning while calling std:this_thread::yield an effective way of reducing the possibility of oversleeping
              – James Picone
              4 hours ago








            • 1




              I don't have personal experience using that for this kind of thing. I'd say it's more suited to things like spin-locks and very short-duration timing spins. I would definitely not want to run a 60Hz game loop with a spin-wait + yield, especially not if I'd also upped the thread priority.
              – paddy
              4 hours ago






            • 1




              Right, so as you edited your comment, then yes that could be a performance tweak. Since the sleep_for can come out late, you can use a shorter sleep than you need, then use yield for tighter spin "sleeps" that pad out any undershooting. That's down to experimentation and black magic.
              – paddy
              4 hours ago












            • I tried both of these, adding a thread sleep for as long as 10ms on each update, and still see the problem :(
              – S. Turnage
              3 hours ago


















            How effective is std::this_thread::yield for this sort of thing? EDIT: i.e. is spinning while calling std:this_thread::yield an effective way of reducing the possibility of oversleeping
            – James Picone
            4 hours ago






            How effective is std::this_thread::yield for this sort of thing? EDIT: i.e. is spinning while calling std:this_thread::yield an effective way of reducing the possibility of oversleeping
            – James Picone
            4 hours ago






            1




            1




            I don't have personal experience using that for this kind of thing. I'd say it's more suited to things like spin-locks and very short-duration timing spins. I would definitely not want to run a 60Hz game loop with a spin-wait + yield, especially not if I'd also upped the thread priority.
            – paddy
            4 hours ago




            I don't have personal experience using that for this kind of thing. I'd say it's more suited to things like spin-locks and very short-duration timing spins. I would definitely not want to run a 60Hz game loop with a spin-wait + yield, especially not if I'd also upped the thread priority.
            – paddy
            4 hours ago




            1




            1




            Right, so as you edited your comment, then yes that could be a performance tweak. Since the sleep_for can come out late, you can use a shorter sleep than you need, then use yield for tighter spin "sleeps" that pad out any undershooting. That's down to experimentation and black magic.
            – paddy
            4 hours ago






            Right, so as you edited your comment, then yes that could be a performance tweak. Since the sleep_for can come out late, you can use a shorter sleep than you need, then use yield for tighter spin "sleeps" that pad out any undershooting. That's down to experimentation and black magic.
            – paddy
            4 hours ago














            I tried both of these, adding a thread sleep for as long as 10ms on each update, and still see the problem :(
            – S. Turnage
            3 hours ago






            I tried both of these, adding a thread sleep for as long as 10ms on each update, and still see the problem :(
            – S. Turnage
            3 hours ago














            up vote
            1
            down vote













            In addition to @paddy's answer I recommend you look into fixed timesteps. If that isn't worth the trouble of implementing then you should also note that SFML has Window.setFramerateLimit(). It's not very precise but most simple games don't need significant precision.






            share|improve this answer





















            • The fixed timesteps link is a good one, and what I used to come up with the code example. I also see the issue even when using SFMLs setFrameLimit. For some reason the clock is jumping a huge amount of time.
              – S. Turnage
              3 hours ago












            • Well the FrameLimit only keeps your loop from running too often on a fast cpu. It doesn't stop the framerate from dropping. What are you running in your background anyway? Could you try on a different machine?
              – bruglesco
              3 hours ago















            up vote
            1
            down vote













            In addition to @paddy's answer I recommend you look into fixed timesteps. If that isn't worth the trouble of implementing then you should also note that SFML has Window.setFramerateLimit(). It's not very precise but most simple games don't need significant precision.






            share|improve this answer





















            • The fixed timesteps link is a good one, and what I used to come up with the code example. I also see the issue even when using SFMLs setFrameLimit. For some reason the clock is jumping a huge amount of time.
              – S. Turnage
              3 hours ago












            • Well the FrameLimit only keeps your loop from running too often on a fast cpu. It doesn't stop the framerate from dropping. What are you running in your background anyway? Could you try on a different machine?
              – bruglesco
              3 hours ago













            up vote
            1
            down vote










            up vote
            1
            down vote









            In addition to @paddy's answer I recommend you look into fixed timesteps. If that isn't worth the trouble of implementing then you should also note that SFML has Window.setFramerateLimit(). It's not very precise but most simple games don't need significant precision.






            share|improve this answer












            In addition to @paddy's answer I recommend you look into fixed timesteps. If that isn't worth the trouble of implementing then you should also note that SFML has Window.setFramerateLimit(). It's not very precise but most simple games don't need significant precision.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 4 hours ago









            bruglesco

            1361110




            1361110












            • The fixed timesteps link is a good one, and what I used to come up with the code example. I also see the issue even when using SFMLs setFrameLimit. For some reason the clock is jumping a huge amount of time.
              – S. Turnage
              3 hours ago












            • Well the FrameLimit only keeps your loop from running too often on a fast cpu. It doesn't stop the framerate from dropping. What are you running in your background anyway? Could you try on a different machine?
              – bruglesco
              3 hours ago


















            • The fixed timesteps link is a good one, and what I used to come up with the code example. I also see the issue even when using SFMLs setFrameLimit. For some reason the clock is jumping a huge amount of time.
              – S. Turnage
              3 hours ago












            • Well the FrameLimit only keeps your loop from running too often on a fast cpu. It doesn't stop the framerate from dropping. What are you running in your background anyway? Could you try on a different machine?
              – bruglesco
              3 hours ago
















            The fixed timesteps link is a good one, and what I used to come up with the code example. I also see the issue even when using SFMLs setFrameLimit. For some reason the clock is jumping a huge amount of time.
            – S. Turnage
            3 hours ago






            The fixed timesteps link is a good one, and what I used to come up with the code example. I also see the issue even when using SFMLs setFrameLimit. For some reason the clock is jumping a huge amount of time.
            – S. Turnage
            3 hours ago














            Well the FrameLimit only keeps your loop from running too often on a fast cpu. It doesn't stop the framerate from dropping. What are you running in your background anyway? Could you try on a different machine?
            – bruglesco
            3 hours ago




            Well the FrameLimit only keeps your loop from running too often on a fast cpu. It doesn't stop the framerate from dropping. What are you running in your background anyway? Could you try on a different machine?
            – bruglesco
            3 hours ago










            up vote
            0
            down vote













            I've used spinning loop plus yield for 1 KHz control loops with good results, but expect some deadline miss (once in thousands cycles also long sleeping times).






            share|improve this answer

























              up vote
              0
              down vote













              I've used spinning loop plus yield for 1 KHz control loops with good results, but expect some deadline miss (once in thousands cycles also long sleeping times).






              share|improve this answer























                up vote
                0
                down vote










                up vote
                0
                down vote









                I've used spinning loop plus yield for 1 KHz control loops with good results, but expect some deadline miss (once in thousands cycles also long sleeping times).






                share|improve this answer












                I've used spinning loop plus yield for 1 KHz control loops with good results, but expect some deadline miss (once in thousands cycles also long sleeping times).







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 36 mins ago









                PeppeDx

                367




                367






















                    S. Turnage is a new contributor. Be nice, and check out our Code of Conduct.










                    draft saved

                    draft discarded


















                    S. Turnage is a new contributor. Be nice, and check out our Code of Conduct.













                    S. Turnage is a new contributor. Be nice, and check out our Code of Conduct.












                    S. Turnage is a new contributor. Be nice, and check out our Code of Conduct.
















                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53735418%2fsteady-clock-skipping-between-updates-in-main-game-loop-c%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Михайлов, Христо

                    Гороховецкий артиллерийский полигон

                    Центральная группа войск