控制每秒函数调用的速率
Control rate of function calls per second
一个操作需要 65 毫秒才能完成。它需要以每秒 特定目标操作数 .[=11 的速度被触发 'numOpr' 次=]
我们如何控制以特定速率触发的操作?
下面是我尝试过的示例,但它似乎并不关心每秒的目标操作数。在所有有效的 targetOps 值下它总是在 ~15ops。
目标环境: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;
}
问题 #1 是您没有初始化 timeBetweenOperation
,因此它将以您的 1/N 速率设置为 0 个滴答。因此,您总是添加 0。您可以通过初始化它来解决这个问题:
std::chrono::duration<double, std::ratio<1, targetOPS>> timeBetweenOperation(1);
问题 #2 是您执行 sleep_until
的方式。你一直在睡觉,直到 now
加上间隔,所以你总是会得到 65ms 加上你的 100ms gab,导致每秒 6 次操作。如果你想要每秒操作 N 次,你需要在执行 65ms 操作之前获取 now
。
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);
}
一个操作需要 65 毫秒才能完成。它需要以每秒 特定目标操作数 .[=11 的速度被触发 'numOpr' 次=]
我们如何控制以特定速率触发的操作?
下面是我尝试过的示例,但它似乎并不关心每秒的目标操作数。在所有有效的 targetOps 值下它总是在 ~15ops。
目标环境: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;
}
问题 #1 是您没有初始化 timeBetweenOperation
,因此它将以您的 1/N 速率设置为 0 个滴答。因此,您总是添加 0。您可以通过初始化它来解决这个问题:
std::chrono::duration<double, std::ratio<1, targetOPS>> timeBetweenOperation(1);
问题 #2 是您执行 sleep_until
的方式。你一直在睡觉,直到 now
加上间隔,所以你总是会得到 65ms 加上你的 100ms gab,导致每秒 6 次操作。如果你想要每秒操作 N 次,你需要在执行 65ms 操作之前获取 now
。
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);
}