...causing the system to freeze due to excess memory allocation. Fortunately it turned out this was not an error in the Scheduler core or memory manager, but rather a sloppiness in the test scaffolding. However, this incident highlights that the memory manager lacks some sanity checks to prevent outright nonsensical allocation requests. Moreover it became clear again that the allocation happens ''already before'' entering the Scheduler — and thus the existing sanity check comes too late. Now I've used the same reasoning also for additional checks in the allocator, limiting the Epoch increment to 3000 and the total memory allocation to 8GiB Talking of Gibitbytes... indeed we could use a shorthand notation for that purpose...
160 lines
4.6 KiB
C++
160 lines
4.6 KiB
C++
/*
|
|
SchedulerStress(Test) - verify scheduler performance characteristics
|
|
|
|
Copyright (C) Lumiera.org
|
|
2023, Hermann Vosseler <Ichthyostega@web.de>
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of
|
|
the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
* *****************************************************/
|
|
|
|
/** @file scheduler-usage-test.cpp
|
|
** unit test \ref SchedulerStress_test
|
|
*/
|
|
|
|
|
|
#include "lib/test/run.hpp"
|
|
#include "test-chain-load.hpp"
|
|
#include "vault/gear/scheduler.hpp"
|
|
#include "lib/time/timevalue.hpp"
|
|
#include "lib/format-cout.hpp"
|
|
#include "lib/test/diagnostic-output.hpp"//////////////////////////TODO work in distress
|
|
//#include "lib/format-string.hpp"
|
|
//#include "lib/test/transiently.hpp"
|
|
//#include "lib/test/microbenchmark.hpp"
|
|
//#include "lib/util.hpp"
|
|
|
|
//#include <utility>
|
|
|
|
using test::Test;
|
|
//using std::move;
|
|
//using util::isSameObject;
|
|
|
|
|
|
namespace vault{
|
|
namespace gear {
|
|
namespace test {
|
|
|
|
// using lib::time::FrameRate;
|
|
// using lib::time::Offset;
|
|
// using lib::time::Time;
|
|
|
|
namespace { // Test definitions and setup...
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @test Investigate and verify non-functional characteristics of the Scheduler.
|
|
* @see SchedulerActivity_test
|
|
* @see SchedulerInvocation_test
|
|
* @see SchedulerCommutator_test
|
|
*/
|
|
class SchedulerStress_test : public Test
|
|
{
|
|
|
|
virtual void
|
|
run (Arg)
|
|
{
|
|
smokeTest();
|
|
generalFuckup();
|
|
walkingDeadline();
|
|
}
|
|
|
|
|
|
/** @test TODO demonstrate sustained operation under load
|
|
* @todo WIP 12/23 🔁 define ⟶ implement
|
|
*/
|
|
void
|
|
smokeTest()
|
|
{
|
|
MARK_TEST_FUN
|
|
TestChainLoad testLoad{128};
|
|
testLoad.configureShape_chain_loadBursts()
|
|
.buildToplolgy()
|
|
.printTopologyDOT();
|
|
|
|
auto stats = testLoad.computeGraphStatistics();
|
|
cout << _Fmt{"Test-Load: Nodes: %d Levels: %d ∅Node/Level: %3.1f Forks: %d Joins: %d"}
|
|
% stats.nodes
|
|
% stats.levels
|
|
% stats.indicators[STAT_NODE].pL
|
|
% stats.indicators[STAT_FORK].cnt
|
|
% stats.indicators[STAT_JOIN].cnt
|
|
<< endl;
|
|
|
|
// while building the calculation-plan graph
|
|
// node hashes were computed, observing dependencies
|
|
size_t expectedHash = testLoad.getHash();
|
|
|
|
// some jobs/nodes are marked with a weight-step
|
|
// these can be instructed to spend some CPU time
|
|
auto LOAD_BASE = 500us;
|
|
testLoad.performGraphSynchronously(LOAD_BASE);
|
|
CHECK (testLoad.getHash() == expectedHash);
|
|
|
|
double referenceTime = testLoad.calcRuntimeReference(LOAD_BASE);
|
|
cout << "refTime(singleThr): "<<referenceTime/1000<<"ms"<<endl;
|
|
|
|
|
|
// Perform through Scheduler----------
|
|
BlockFlowAlloc bFlow;
|
|
EngineObserver watch;
|
|
Scheduler scheduler{bFlow, watch};
|
|
|
|
double performanceTime =
|
|
testLoad.setupSchedule(scheduler)
|
|
.withLoadTimeBase(LOAD_BASE)
|
|
.withJobDeadline(50ms)
|
|
.launch_and_wait();
|
|
|
|
cout << "runTime(Scheduler): "<<performanceTime/1000<<"ms"<<endl;
|
|
|
|
// invocation through Scheduler has reproduced all node hashes
|
|
CHECK (testLoad.getHash() == expectedHash);
|
|
}
|
|
|
|
|
|
|
|
/** @test TODO
|
|
* @todo WIP 12/23 🔁 define ⟶ implement
|
|
*/
|
|
void
|
|
generalFuckup()
|
|
{
|
|
UNIMPLEMENTED("tbd");
|
|
}
|
|
|
|
|
|
|
|
/** @test TODO
|
|
* @todo WIP 12/23 🔁 define ⟶ implement
|
|
*/
|
|
void
|
|
walkingDeadline()
|
|
{
|
|
}
|
|
};
|
|
|
|
|
|
/** Register this test class... */
|
|
LAUNCHER (SchedulerStress_test, "unit engine");
|
|
|
|
|
|
|
|
}}} // namespace vault::gear::test
|