I am using benchmark library to benchmark some codes. I want to call a setup method before calling the actual benchmark code one time and not to be repeated everytime, for multiple benchmark method calls.. For e.g:
static void BM_SomeFunction(benchmark::State& state) {
// Perform setup here
for (auto _ : state) {
// This code gets timed
}
}
As we can see the setup code will be called multiple times here, for the range I specify. I did have a look at the fixture tests. But my question is can it be done without using fixture tests. And if yes then how can we do it?
As far as I can remember, the function is called multiple times, since benchmark dynamically decides how many times your benchmark needs to be run in order to get reliable results. If you don't want to use fixtures, there are multiple workarounds. You can use a global or static class member bool to check if the setup function was already called (don't forget to set it after the setup routine has run). Another possibility is to use a Singleton that calls the setup method in its ctor:
class Setup
{
Setup()
{
// call your setup function
std::cout << "singleton ctor called only once in the whole program" << std::endl;
}
public:
static void PerformSetup()
{
static Setup setup;
}
};
static void BM_SomeFunction(benchmark::State& state) {
Setup::PerformSetup()
for (auto _ : state) {
// ...
}
}
However, fixtures are quite simple to use and are made for such use-cases.
Define a fixture class which inherits from benchmark::Fixture:
class MyFixture : public benchmark::Fixture
{
public:
// add members as needed
MyFixture()
{
std::cout << "Ctor only called once per fixture testcase hat uses it" << std::endl;
// call whatever setup functions you need in the fixtures ctor
}
};
Then use the BENCHMARK_F macro to use your fixture in the test.
BENCHMARK_F(MyFixture, TestcaseName)(benchmark::State& state)
{
std::cout << "Benchmark function called more than once" << std::endl;
for (auto _ : state)
{
//run your benchmark
}
}
However, if you use the fixture in multiple benchmarks, the ctor will be called multiple times. If you really need a certain setup function to be called only once during the whole benchmark, you can use a Singleton or a static bool to work around this as described earlier. Maybe benchmark also has a built-in solution for that, but I don't know it.
Alternative to Singleton
If you don't like the singleton class, you can also use a global function like this:
void Setup()
{
static bool callSetup = true;
if (callSetup)
{
// Call your setup function
}
callSetup = false;
}
Greetings
Related
I've implemented a C++ Class that will execute something in a timed cycle using a thread. The thread is set to be scheduled with the SCHED_DEADLINE scheduler of the Linux kernel. To setup the Scheduler the process running this must have certain Linux capabilities.
My question is, how to test this?
I can of course make a unit test and create the threat, do some counting an exit the test after a time to validate the cycle counter but that only works if the unit test is allowed to apply the right scheduler. If not, the default scheduler applies and the timing of the cyclic loops will be immediate and therefore executes a different behaviour.
How would you test this scenario?
Some Code Example:
void thread_handler() {
// setup SCHED_DEADLINE Parameters
while (running) {
// execute application logic
sched_yield();
}
}
There two separate units to test here. First the cyclic execution of code and second the strategy with the os interface. The first unit would look like this:
class CyclicThread : public std::thread {
public:
CyclicThread(Strategy& strategy) :
std::thread(bind(&CyclicThread::worker, this)),
strategy(strategy) { }
add_task(std::function<void()> handler) {
...
}
private:
Strategy& strategy;
void worker() {
while (running) {
execute_handler()
strategy.yield();
}
}
}
This is fairly easy to test with a mock object of the strategy.
The Deadline scheduling strategy looks like this:
class DeadlineStrategy {
public:
void yield() {
sched_yield();
}
}
This class can also be tested fairly easy by mocking the sched_yield() system call.
I have a code snippet I need to benchmark composed of 2 parts, first the state needs to be set exactly once, next I need to actually benchmark a function.
My code looks like this:
static void BM_LoopTime(benchmark::State& state)
{
MasterEngine engine;
for (auto _ : state)
{
engine.LoopOnce();
}
}
BENCHMARK(BM_LoopTime);
In my output I am getting:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Pointer already set
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Multiple times, which is a custom error message that indicates a very important pointer that should only ever be touched once is trying to be overwritten.
Calling that code multiple times is undefined behaviour in my implementation. How can I call the object initialization exactly once and then tell it to call the loop?
This is a work around that I found that's good enough for my use case but I am still looking for better solutions:
class MyFixture : public benchmark::Fixture
{
public:
std::unique_ptr<MasterEngine> engine;
void SetUp(const ::benchmark::State& state)
{
if(engine.get() == nullptr)
engine = std::make_unique<MasterEngine>();
}
void TearDown(const ::benchmark::State& state)
{
}
};
I'm running a bit of code on an Arduino machine that uses C++. The setup (very roughly) is like below in the main function. The example is fairly contrived, and the code design doesn't really pass the smell check, but it's the best I can do.
There's a 3rd party WiFi library that I'm trying to add an "onDisconnect" hook to. When my TaskRunner class executes, I attach a function to this hook so that when the WiFi disconnects, my task runner is notified.
The challenge is I don't know the language well enough to assign an anonymous function that also keeps the "isWifiConnected in scope. I'm somewhat learning C++ on the fly so please feel free to change the title of the question as I might not even be asking the right one.
Note that I may not be looking for an anonymous function. I'm trying to update the isWifiConnected property when onDisconnect() is called.
#include <iostream>
using namespace std;
// A 3rd Party class
// https://github.com/Hieromon/AutoConnect/blob/master/src/AutoConnect.h
// https://github.com/Hieromon/AutoConnect/blob/master/src/AutoConnect.cpp
class AutoConnect {
public:
AutoConnect(){};
// I add this to the class as a hook to be called at about
// line 549 code block where AutoConnect calls disconnect code
void (*onDisconnect)();
};
void onDisconnect(){
cout << "Disconnecting!" << endl;
cout << "But how to make isWifiConnected false? I don't have access :/";
};
// My task runner
class TaskRunner {
public:
bool isWifiConnected;
AutoConnect *connector;
TaskRunner(AutoConnect & connector){
this->connector = & connector;
}
void execute(){
isWifiConnected = true;
// run some WiFi connection code ...
// assign the onDisconnect hook to be run when it disconnects
connector -> onDisconnect = onDisconnect;
// but how can I update "isWifiConnected" = false when the onDisconnect runs
// In JavaScript, I could do
/*
connector -> onDisconnect = function(){
// variable stays in scope due to closure.
isWifiConnected = false;
}
*/
}
};
int main() {
cout<<"Running ..." << endl;
// Instantiate my classes and inject WifiConnector into my task runner
AutoConnect connector;
TaskRunner runner = TaskRunner(connector);
// Simulate an event loop for effect
for(int i = 0; i < 10; i++){
if(i == 0) runner.execute();
// on some other condition, Wifi is disconnected
if(i == 9) connector.onDisconnect();
}
return 0;
}
Any ideas on how to update the TaskRunner's isWifiConnected variable? I've tried various pointer combinations but can't quite get it right.
Other issues with the code aside (see question comments):
You can store a lambda in a std::function:
Instead of void (*onDisconnect)(); declare it std::function<void()> onDisconnect;. (requires #include<functional>)
Then you can store a capturing lambda in it:
connector->onDisconnect = [this](){
isWifiConnected = false;
};
Since this stores a pointer to *this, you must make sure the the TaskRunner object outlives any potential call to this hook/lambda. Otherwise your program will have undefined behavior.
In particular currently the TaskRunner is declared after the AutoConnect object in main, meaning that the latter will be destroyed before the AutoConnect and therefore there will be a possibility of the lambda being called when TaskRunner has already been destroyed. This is particularly the case if AutoConnect's destructor may call the lambda. Whether it does or not I don't know.
I'm trying to work out a design predicament I have.
ClassWithLongOperation
{
Run()
{
RecrusiveOperation();
}
RecrusiveOperation()
{
/* RECURSION */
}
}
MyThread
{
ClassWithLongOperation Op1(10);
Op1.Run(); // Takes several minutes.
ClassWithLongOperation Op2(20);
Op2.Run();
SomeOtherClassWithLongOperation Op3;
Op3.Run();
// Do some other stuff
}
The GUI starts MyThread, which runs for a good 5-6 minutes. I want to be able to have a big fat Cancel button on my GUI, so the user can cancel the operation.
I could create a global boolean variable bCancelled, and check if its been set in RecursiveOperation, but I want to be a good C++ & OO programmer and avoid global variables. Especially if they would have to spread across multiple files.
So how would I (following good design) safely cancel MyThread? What could I change in my setup to allow this?
I'm also using _beginthreadex to start the thread, but I could use boost if it would allow for an easier solution.
Your flag not need to be global to your entire program, but it needs to be visible to your class code. Create the flag to be a private instance member and a public function to change it to false/true. In your recursive function, test its value to verify if the task should continue. When you want, set its value to false (through the function of course) to stop the recursive calls, i.e., when the user clicks the button you call the function in the desired instance. This way you will not break any OO principle, since you have a private flag and a public member function to safely change it.
Using a global variable is actually not the worst thing in the world. Having a proliferation of unnecessary global variables leads to maintenance nightmares, but it actually sounds like a quick and easy-to-understand solution here. But if you want a clean OO solution, this is certainly possible:
EDIT My original post overlooked the fact that you want to be able to run several operations in sequence, and if any of them is cancelled, none of the remaining operations are performed. This means it's more useful to keep the bool flag inside the canceller, instead of separately in each cancellable operation; and exceptions are the nicest way to handle the actual control flow. I've also tightened up a few things (added volatile for the flag itself, made names clearer, restricted unnecessary access rights).
// A thing that can cancel another thing by setting a bool to true.
class Canceller {
public:
Canceller : cancelledFlag(false) {}
void RegisterCancellee(Cancellee const& c) {
c.RegisterCanceller(cancelledFlag);
}
void Cancel() {
cancelledFlag = true;
}
private:
volatile bool cancelledFlag;
};
class CancelButton : public Canceller {
...
// Call Cancel() from on-click event handler
...
};
class Cancellation : public std::exception {
public:
virtual const char* what() const throw() {
return "User cancelled operation";
}
};
// A thing that can be cancelled by something else.
class Cancellee {
friend class Canceller; // Give them access to RegisterCanceller()
protected:
Cancellee() : pCancelledFlag(0) {}
// Does nothing if unconnected
void CheckForCancellation() {
if (pCancelledFlag && *pCancelledFlag) throw Cancellation();
}
private:
void RegisterCanceller(volatile bool& cancelledFlag) {
pCancelledFlag = &cancelledFlag;
}
volatile bool* pCancelledFlag;
};
class Op1 : public Cancellee { // (And similarly for Op2 and Op3)
...
// Poll CheckForCancellation() inside main working loop
...
};
MyThread
{
CancelButton cancelButton("CANCEL!");
try {
ClassWithLongOperation Op1(10);
cancelButton.RegisterCancellee(Op1);
Op1.Run(); // Takes several minutes.
ClassWithLongOperation Op2(20);
cancelButton.RegisterCancellee(Op2);
Op2.Run();
SomeOtherClassWithLongOperation Op3;
cancelButton.RegisterCancellee(Op3);
Op3.Run();
} catch (Cancellation& c) {
// Maybe write to a log file
}
// Do some other stuff
}
The "double bouncing" registration allows the canceller to give access to a private flag variable.
The most important thing is to not use thread termination functions, except in very specialised cases. Why? They don't run destructors. Nor do they give the target thread any chance to "clean up".
Instead of using a global variable, add a method to ClassWithLongOperation and/or MyThread, something like cancelOperation() that will set an internal boolean variable. The appropriate class methods would then need to check the variable at appropriate moments.
You could implement a Stop() method for your ClassWithLongOperation and have the event handler for BigFatCancelButton to call this Stop() method for the current operation.
... Or add a Stop() method to the Thread class and make the work objects be aware of the threads they're running in. You may as well throw in a Stop() method for the work objects. Depending on what's more important: Stop the thread or the work object.
I have code I want to extract from a unit test to make my test method clearer:
Check check;
check.Amount = 44.00;
// unit testing on the check goes here
How should I extract this? Should I use a pointer to the check or some other structure to make sure it's still allocated when I use the object?
I don't want to use a constructor because I want to isolate my test creation logic with production creation logic.
In a modern unit testing framework you usually have testing case as
class MyTest: public ::testing::Test {
protected:
MyTest() {}
~MyTest() {}
virtual void SetUp() {
// this will be invoked just before each unit test of the testcase
// place here any preparations or data assembly
check.Amount = 44.00;
}
virtual void TearDown() {
// this will be inkoved just after each unit test of the testcase
// place here releasing of data
}
// any data used in tests
Check check;
};
// single test that use your predefined preparations and releasing
TEST_F(MyTest, IsDefaultInitializedProperly) {
ASSERT_FLOAT_EQ(44., check.Amount);
}
// and so on, SetUp and TearDown will be done from scratch for every new test
You can find such functionality i.e. in Google Test Framework (https://github.com/google/googletest/)