Closed PeterBowman closed 3 years ago
Test code:
#include <algorithm>
#include <memory>
#include <vector>
#include <yarp/os/LogStream.h>
#include <yarp/os/Network.h>
#include <yarp/os/Timer.h>
int main()
{
yarp::os::Network::initMinimum(yarp::os::YARP_CLOCK_SYSTEM);
std::vector<std::unique_ptr<yarp::os::Timer>> timers;
for (auto i = 0; i < 30; i++)
{
auto period = 0.01 * (i + 1); // min: 0.01 s, max: 0.3 s
auto timer = std::make_unique<yarp::os::Timer>(yarp::os::TimerSettings(period), [i](const auto & event)
{
volatile long long int result = 1;
for (int j = 0; j < (i + 1) * 10000; j++) { result += j; }
yInfo() << "timer" << i + 1 << "reporting count" << event.runCount << "and result" << result;
return true;
},
false); // true: multi-thread, false: mono-thread
timer->start();
timers.push_back(std::move(timer));
}
yarp::os::SystemClock::delaySystem(20.0);
std::for_each(timers.cbegin(), timers.cend(), [](const auto & timer) { timer->stop(); });
yarp::os::Network::finiMinimum();
return 0;
}
This creates 30 timers with distinct periods and performs some CPU-intensive operation on each step. Results on a 16-core CPU:
There is not much difference as fas as I can tell. I have not tested timer accuracy in the mono-thread scenario, but this is not critical. I'm therefore prone to switch to mono-thread (third parameter equal to false
), note we are already using plenty of threads elsewhere.
By the way, YARP 3.3.3 is required for mono-thread because of https://github.com/robotology/yarp/pull/1993. We are safe, though.
A monitor worker is responsible for periodically checking the boot-up and heartbeat signals broadcast by an iPOS drive. In our code, we conceived said worker as a callback function orquestrated by
yarp::os::Timer
:https://github.com/roboticslab-uc3m/yarp-devices/blob/d8f244ce3fd8d909a366c7675919f91bd3879519/libraries/YarpPlugins/TechnosoftIpos/DeviceDriverImpl.cpp#L170
The third parameter to the constructor is
true
. This means eachTechnosoftIpos
device instance creates its own thread for this specific purpose. If it's set tofalse
, the callback is called from within a shared, singletonPeriodicThread
instance common to all timers configured in this manner.In other words, if we ever manage to run a whole-body 28-dof launchCanBus, switching from
true
tofalse
would mean squashing 28 independent threads into only one. This issue is meant for investigating the pros and cons, especially regarding CPU resource usage.