1212#include < modm/board.hpp>
1313#include < modm/debug/logger.hpp>
1414#include < modm/processing.hpp>
15+ #include < modm/driver/time/cycle_counter.hpp>
1516
1617using namespace Board ;
1718using namespace std ::chrono_literals;
1819
19- constexpr uint32_t cycles = 1'000 '000 ;
20+ constexpr uint32_t cycles = 100 '000 ;
2021volatile uint32_t f1counter = 0 , f2counter = 0 ;
2122uint32_t total_counter=0 ;
23+ modm_fastdata modm::CycleCounter counter;
2224
2325void
2426fiber_function1 ()
@@ -54,24 +56,57 @@ struct Test
5456 volatile uint32_t f4counter{0 };
5557} test;
5658
57- modm_faststack modm::fiber::Stack<2048 > stack1;
58- modm_faststack modm::fiber::Stack<2048 > stack2;
59- modm_faststack modm::fiber::Stack<2048 > stack3;
60- modm_faststack modm::fiber::Stack<2048 > stack4;
61- modm_fastdata modm::Fiber fiber1 (stack1, fiber_function1);
62- modm_fastdata modm::Fiber fiber2 (stack2, [](){ fiber_function2 (cycles); });
63- modm_fastdata modm::Fiber fiber3 (stack3, [](){ test.fiber_function3 (); });
64- modm_fastdata modm::Fiber fiber4 (stack4, [cyc=uint32_t (0 )]() mutable { cyc++; test.fiber_function4 (cyc); });
59+ // Single purpose fibers to time the yield
60+ modm_faststack modm::Fiber<> fiber_y1 ([](){ modm::fiber::yield (); counter.stop (); });
61+ modm_faststack modm::Fiber<> fiber_y2 ([](){ counter.start (); modm::fiber::yield (); });
62+
63+ modm_faststack modm::Fiber<> fiber1 (fiber_function1, modm::fiber::Start::Later);
64+ modm_faststack modm::Fiber<> fiber2 ([](){ fiber_function2 (cycles); }, modm::fiber::Start::Later);
65+ modm_faststack modm::Fiber<> fiber3 ([](){ test.fiber_function3 (); }, modm::fiber::Start::Later);
66+ modm_faststack modm::Fiber<> fiber4 ([cyc=uint32_t (0 )]() mutable
67+ { cyc = cycles; test.fiber_function4 (cyc); }, modm::fiber::Start::Later);
68+
69+ // Restartable Fibers
70+ extern modm::Fiber<> fiber_pong;
71+ extern modm::Fiber<> fiber_ping;
72+ modm_faststack modm::Fiber<> fiber_ping ([](){
73+ MODM_LOG_INFO << " ping = " << fiber_ping.stack_usage () << modm::endl;
74+ modm::fiber::sleep (1s);
75+ fiber_pong.start ();
76+ }, modm::fiber::Start::Later);
77+ modm_faststack modm::Fiber<> fiber_pong ([](){
78+ MODM_LOG_INFO << " pong = " << fiber_pong.stack_usage () << modm::endl;
79+ modm::fiber::sleep (1s);
80+ fiber_ping.start ();
81+ }, modm::fiber::Start::Later);
6582
6683// Blue pill (M3 72MHz): Executed 1000000 in 1098591us (910256.88 yields per second)
6784// Feather M0 (M0+ 48MHz): Executed 1000000 in 1944692us (514220.25 yields per second)
6885int
6986main ()
7087{
7188 Board::initialize ();
89+ counter.initialize ();
7290 MODM_LOG_INFO << " Starting fiber modm::yield benchmark..." << modm::endl;
7391 MODM_LOG_INFO.flush ();
7492
93+ fiber_y1.watermark_stack ();
94+ fiber_y2.watermark_stack ();
95+ // fiber_y1, fiber_y2 were autostarted
96+ {
97+ modm::atomic::Lock l;
98+ modm::fiber::Scheduler::run ();
99+ }
100+
101+ MODM_LOG_INFO << " Y1 stack usage: = " << fiber_y1.stack_usage () << modm::endl;
102+ MODM_LOG_INFO << " Y2 stack usage: = " << fiber_y2.stack_usage () << modm::endl;
103+ MODM_LOG_INFO.flush ();
104+
105+ // the rest is manually started
106+ fiber1.start (); fiber1.watermark_stack ();
107+ fiber2.start (); fiber2.watermark_stack ();
108+ fiber3.start (); fiber3.watermark_stack ();
109+ fiber4.start (); fiber4.watermark_stack ();
75110 const modm::PreciseTimestamp start = modm::PreciseClock::now ();
76111 modm::fiber::Scheduler::run ();
77112 const auto diff = (modm::PreciseClock::now () - start);
@@ -81,8 +116,19 @@ main()
81116 MODM_LOG_INFO << ((total_counter * 1'000'000ull ) / std::chrono::microseconds (diff).count ());
82117 MODM_LOG_INFO << " yields per second, " ;
83118 MODM_LOG_INFO << (std::chrono::nanoseconds (diff).count () / total_counter);
84- MODM_LOG_INFO << " ns per yield" << modm::endl;
85- MODM_LOG_INFO.flush ();
119+ MODM_LOG_INFO << " ns per yield slice" << modm::endl;
120+ MODM_LOG_INFO << counter.cycles () << " cycles = " << counter.nanoseconds ();
121+ MODM_LOG_INFO << " ns per single yield" << modm::endl;
122+
123+ MODM_LOG_INFO << " F1 stack usage = " << fiber1.stack_usage () << modm::endl;
124+ MODM_LOG_INFO << " F2 stack usage = " << fiber2.stack_usage () << modm::endl;
125+ MODM_LOG_INFO << " F3 stack usage = " << fiber3.stack_usage () << modm::endl;
126+ MODM_LOG_INFO << " F4 stack usage = " << fiber4.stack_usage () << modm::endl;
127+
128+ fiber_ping.watermark_stack ();
129+ fiber_pong.watermark_stack ();
130+ fiber_ping.start ();
131+ modm::fiber::Scheduler::run ();
86132
87133 while (1 ) ;
88134 return 0 ;
0 commit comments