0

Consider:

#include <time.h>
#include <windows.h>

clock_t tStart = clock();
for (int i = 0; i < 10; i++) {
    Sleep(10);
}
printf("Time taken: %.3fs\n", (double)(clock() - tStart) / CLOCKS_PER_SEC);

Time taken: 0.102 s (varied)

clock_t tStart = clock();
for (int i = 0; i < 10; i++) {
    doSomething();
    Sleep(10);
}
printf("Time taken: %.3fs\n", (double)(clock() - tStart) / CLOCKS_PER_SEC);

Time taken: 0.105 s (varied)

How can I adjust my Sleep() so that the program consistently ends on printing 0.100 s each time? (and that doSomething(); executes exactly every 0.010s). Is that even possible?

So far I have tried to calculate the time each iteration of the loop takes and decrease the following Sleep() by that amount, but to no avail. Additionally, if making something execute every 0.010 s is not possible, what is the minimum time I can consistently make something execute at?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
T. Michael
  • 11
  • 1
  • 2
  • what exactly do you mean with "exact" ? For example, is it important that the sleep is not longer/shorter than `0.1s` or is it important that sleeping x times adds up to `x * 0.1s` as accurately as possible? You cant have both – 463035818_is_not_an_ai Oct 06 '17 at 16:20
  • 1
    Something to be aware of is the precision of the clock being used. For example, the Windows clock by default ticks 64 times per second. See [MSDN](https://msdn.microsoft.com/en-us/library/windows/desktop/dd743626%28v=vs.85%29.aspx) for more info on changing resolution. – Bonsaigin Oct 06 '17 at 16:26
  • Apologies, what I meant what I want exactly every 10ms the function doSomething() to be called, because the doSomething() function takes time itself, the next call on doSomething() will sometimes not be exactly 10ms after the last. – T. Michael Oct 06 '17 at 16:27

1 Answers1

8

The technique that I (and I assume many others) use in games is to deal in absolute time. This automatically adjusts for the duration of the action.

e.g.

#include <chrono>
#include <thread>
#include <iostream>

using namespace std::literals;
using clock_type = std::chrono::high_resolution_clock;

void doSomething() {}

int main()
{
    auto when_started = clock_type::now(); 
    auto target_time = when_started + 10ms;
    for (int i = 0; i < 10; i++) {
        doSomething();
        std::this_thread::sleep_until(target_time);
        target_time += 10ms;
    }
    auto now = clock_type::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(now - when_started).count() << "ms\n";
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • After implementing this, my function doSomething() will for some reason not work, the function takes 3 parameters, `(INPUT *buffer, int x, int y)` and within the block of the function it calls `SendInput(1, buffer, sizeof(INPUT));` – T. Michael Oct 06 '17 at 16:36
  • Apologies I explained that poorly, `doSomething()` contains `SendInput(1, buffer, sizeof(INPUT));` in it's body, for me actually calling `doSomething()` I use `doSomething(buffer, 1, 1);` where buffer is instantiated/assigned (not sure on correct terminology) using `INPUT buffer[1];` – T. Michael Oct 06 '17 at 16:46
  • @T.Michael i'd love to help, but without seeing an MCVE it's not possible. Suggest opening a new question with a minimal example of what's not working. – Richard Hodges Oct 06 '17 at 16:56
  • I appreciate you wanting to help, It seems if I increase the loop to 200 iterations my function will work, infact the function was working the whole time I just think `SendInput(1, buffer, sizeof(INPUT));` wasn't getting a chance to execute before the program ended; this bothers me because I want `SendInput(1, buffer, sizeof(INPUT));` to execute every 10 ms however it may not be possible seeing these results. Thanks for the help though! – T. Michael Oct 06 '17 at 17:28