Точная выборка в переполнении стека

Я хочу сэмплировать значения, которые я получаю из gpio 4000 раз в секунду, в настоящее время я делаю что-то подобное:

std::vector<int> sample_a_chunk(unsigned int rate, unsigned int block_size_in_seconds) {
std::vector<std::int> data;
constexpr unsigned int times = rate * block_size_in_seconds;
constexpr unsigned int delay = 1000000 / rate; // microseconds
for (int j=0; j<times; j++) {
data.emplace_back(/* read the value from the gpio */);
std::this_thread::sleep_for(std::chrono::microseconds(delay));
}
return data;
}

пока по ссылке sleep_for гарантированно ждать по крайней мере указанное количество времени.

Как я могу заставить мою систему ждать точный количество времени или хотя бы достижение максимально возможной точности?
Как я могу быть уверен в разрешении моей системы по времени?

2

Решение

Я думаю, что лучшее, что вы можете достичь, это использовать абсолютный время, чтобы избежать дрейфа.

Что-то вроде этого:

std::vector<int> sample_a_chunk(unsigned int rate,
unsigned int block_size_in_seconds)
{
using clock = std::chrono::steady_clock;

std::vector<int> data;

const auto times = rate * block_size_in_seconds;
const auto delay = std::chrono::microseconds{1000000 / rate};

auto next_sample = clock::now() + delay;

for(int j = 0; j < times; j++)
{
data.emplace_back(/* read the value from the gpio */);

std::this_thread::sleep_until(next_sample);

next_sample += delay; // don't refer back to clock, stay absolute
}
return data;
}
3

Другие решения

я хотел бы использовать повышение :: ASIO :: deadline_timer.

#include <vector>

#define BOOST_ERROR_CODE_HEADER_ONLY 1
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

std::vector<int> sample_a_chunk(unsigned int rate, unsigned int block_size_in_seconds) {
std::vector<int> data;
const unsigned int times = rate * block_size_in_seconds;
auto expiration_time = boost::posix_time::microsec_clock::local_time();
const auto delay = boost::posix_time::microseconds(1000000/rate);
boost::asio::io_service io;
boost::asio::deadline_timer t(io);

for (unsigned int j=0; j < times; j++) {
expiration_time += delay;
data.emplace_back(/* read the value from the gpio */);
t.expires_at(expiration_time);
t.wait();
}
return data;
}
0

По вопросам рекламы [email protected]