2

I am trying to get 1 millisecond delay but i am getting 15 times higher.I have also tried with windows Sleep(1) function which was also giving me the same result.

why am i not getting exact millisecond delay?

Where as it works with 1 second delay.

#include <iostream>
#include <Windows.h>
#include <thread>
#include <chrono>

void counter1();

auto main() -> int
{

    std::thread p(&counter1);
    p.join();
    return 0;
}

void counter1()
{
    int nStep = 0;
    const int STEP = 1000;
    auto start = std::chrono::high_resolution_clock::now();
    for (;;)
    {
        ++nStep; // incrementing every millisecond
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
        if (nStep == STEP) {  // compares at second
            auto duration = std::chrono::high_resolution_clock::now() - start;
            std::cout << "counter took " <<
                std::chrono::duration_cast<std::chrono::seconds>(duration).count()
                << "seconds \n";
            start = std::chrono::high_resolution_clock::now();
            nStep = 0;
        }
    }
}

Output of this program: https://i.stack.imgur.com/AVZDV.png

Sam Mason
  • 15,216
  • 1
  • 41
  • 60
Nilesh Solanki
  • 336
  • 4
  • 19
  • I wouldn't be surprised about `sleep_for` giving CPU time slice back to OS, similarly as [`yield`](https://en.cppreference.com/w/cpp/thread/yield) does. In that case, the thread would have to wait until getting next CPU slice from OS, which typically is quite longer than 1 ms. If you tried to avoid by busy wait – bad luck, thread's CPU slice might end regularly right while busy waiting, and you get the same effect... – Aconcagua Jun 18 '20 at 09:11
  • @Aconcagua that's awesome. it worked. thank you so much But it's not recommended as it's using higher Power usage and CPU. – Nilesh Solanki Jun 18 '20 at 09:16
  • No guarantee that it always works, though, as mentioned. Threads get a specific amount of time they are allowed to use the CPU – then they get preempted (i. e. CPU is assigned to another thread – unless there are not more threads than CPU cores). If preemption occurs right while busy waiting, you get the same delay. Only chances for this occurring are reduced compared to your previous solution. – Aconcagua Jun 18 '20 at 09:27

2 Answers2

5

You are not getting the expected results, because your expectations are off. sleep_for is not to wait for exact time. From cppreference:

Blocks the execution of the current thread for at least the specified sleep_duration.

This function may block for longer than sleep_duration due to scheduling or resource contention delays.

The standard recommends that a steady clock is used to measure the duration. If an implementation uses a system clock instead, the wait time may also be sensitive to clock adjustments.

Exact timing typically requires dedicated hardware. Expecting 1ms from a desktop pc is rather optimistic.

On top of that the time you measure is not only from sleep_for.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
0

This happens because of 2 things.

  1. waiting is not the only thing you are doing, incrementation and if statement checks also take time.

  2. No clock is perfect

Also if you want an infinite loop while(true) is way better looking

SzymonO
  • 432
  • 3
  • 15
  • 1
    `for(;;)` is fully standard and totally fine – many consider it superior, have even seen a coding guide mandating it (but that went too far in my eyes) ;) – Aconcagua Jun 18 '20 at 08:46
  • @Aconcagua wow never heard of it :o can you provide a link to some article explaining it`s superiority? – SzymonO Jun 18 '20 at 08:48
  • Cannot prove, coming from 15 years of experience. Those voting for `for(;;)` argumented that there's no visible condition check (rather poor argument, admitted). Note that superiority in this case is a matter of personal taste anyway (right as your statement of the other loop looking better), technically, both variants should result simply in an unconditional branch at the end of the translated loop body, so they are fully equivalent. – Aconcagua Jun 18 '20 at 08:55
  • Thank you @SzymonO. I know that incrementation and if statement will take time but as i read that prefix incrementation requires 1 machine cycle and let's assume that if statement will take 2 cpu cycle.and i am running this program on Processor i7-8700CPU @ 3.20GHz. So i think that it shouldn't be problem for this simple program. – Nilesh Solanki Jun 18 '20 at 08:59
  • 1
    https://stackoverflow.com/a/2611529/1312382 – and if you look around here on SO, you'll find opposite oppinions as well... – Aconcagua Jun 18 '20 at 09:00