Home > Software design >  Control rate of function calls per second
Control rate of function calls per second

Time:03-10

An operation takes 65ms to complete. It needs to be triggered 'numOpr' times at a specific target operations per second.

How do we control the operation to be trigged at a specific rate?

Below is a sample that I tried but it doesn't seem to care about target operations per second. It is always at ~15ops at all valid targetOps values.

Target Environment : gcc5.x, C 11

#include <iostream>
#include <chrono>
#include <thread>
int main()
{
    float ops;
    
    //target number of operations
    const std::intmax_t targetOPS = 10;
    
    //number of operations
    const std::size_t numOpr = 20;
    
    std::chrono::duration<double, std::ratio<1, targetOPS>> timeBetweenOperation;
    std::chrono::time_point<std::chrono::steady_clock, decltype(timeBetweenOperation)> tp;

    std::chrono::time_point<std::chrono::high_resolution_clock> started = std::chrono::high_resolution_clock::now();

    //need to run some operation 10 times at specific intervals
    for(size_t i= 0; i<numOpr;i  ){
        //Some operation taking 65ms 
        std::this_thread::sleep_for(std::chrono::milliseconds(65));
        
        //delay between each operation if required to reach targetOPS
        tp = std::chrono::steady_clock::now()   timeBetweenOperation;
        std::this_thread::sleep_until(tp);
    }
    std::chrono::time_point<std::chrono::high_resolution_clock> now = std::chrono::high_resolution_clock::now();
    auto dt_us = std::chrono::duration_cast<std::chrono::microseconds> (now - started).count ();
     if (dt_us > 0)
     {
       ops = numOpr * 1000000.0 / dt_us;
     }
     else
     {
       ops = 0.0;
     }
     
     std::cout<<"Operations per second: "<< ops <<std::endl;
     std::cout<<"Target operations per second: ~"<< targetOPS <<std::endl;
}

CodePudding user response:

Problem #1 is that you didn't initialize timeBetweenOperation, so it will be set to 0 ticks at your 1/N rate. Thus, you are always adding 0. You can fix that by initializing it:

    std::chrono::duration<double, std::ratio<1, targetOPS>> timeBetweenOperation(1);

Problem #2 is the way you are doing the sleep_until. You are sleeping until now plus the interval, so you'll always get 65ms PLUS your 100ms gab, resulting in 6 ops per second. If you want the operation N times per second, you'll need to grab now BEFORE you do the 65ms operation.

    for(size_t i= 0; i<numOpr;i  ){        
        //Compute target endpoint
        tp = std::chrono::steady_clock::now()   timeBetweenOperation;
        // Some operation taking 65ms 
        std::this_thread::sleep_for(std::chrono::milliseconds(65));
        std::this_thread::sleep_until(tp);
    }
  • Related