2
2
3
3
This version is a "drop in" replacement for official ` uasyncio ` . Existing
4
4
applications should run under it unchanged and with essentially identical
5
- performance.
5
+ performance except that task cancellation and timeouts are expedited "soon"
6
+ rather than being deferred until the task is next scheduled.
7
+
8
+ "Priority" features are only enabled if the event loop is instantiated with
9
+ specific arguments.
6
10
7
- This version has the following features:
11
+ This version has the following features relative to official V2.0:
12
+ * Timeouts and task cancellation are handled promptly, rather than being
13
+ deferred until the coroutine is next scheduled.
8
14
* I/O can optionally be handled at a higher priority than other coroutines
9
15
[ PR287] ( https://github.com/micropython/micropython-lib/pull/287 ) .
10
16
* Tasks can yield with low priority, running when nothing else is pending.
@@ -18,7 +24,7 @@ This version has the following features:
18
24
is called with a generator function
19
25
[ PR292] ( https://github.com/micropython/micropython-lib/pull/292 ) . This traps
20
26
a common coding error which otherwise results in silent failure.
21
- * The presence of the ` fast_io ` version can be tested at runtime.
27
+ * The presence and version of the ` fast_io ` version can be tested at runtime.
22
28
* The presence of an event loop instance can be tested at runtime.
23
29
* ` run_until_complete(coro()) ` now returns the value returned by ` coro() ` as
24
30
per CPython
@@ -31,6 +37,12 @@ adding just one line of code. This implies that if official `uasyncio` acquires
31
37
a means of prioritising I/O other than that in this version, application code
32
38
changes should be minimal.
33
39
40
+ #### Changes incompatible with prior versions
41
+
42
+ V0.24
43
+ The ` version ` bound variable now retuens a 2-tuple.
44
+
45
+ Prior versions.
34
46
The high priority mechanism formerly provided in ` asyncio_priority.py ` was a
35
47
workround based on the view that stream I/O written in Python would remain
36
48
unsupported. This is now available so ` asyncio_priority.py ` is obsolete and
@@ -63,7 +75,7 @@ formerly provided by `asyncio_priority.py` is now implemented.
63
75
The basic approach is to install and test ` uasyncio ` on the target hardware.
64
76
Replace ` core.py ` and ` __init__.py ` with the files in the ` fast_io ` directory.
65
77
66
- The current MicroPython release build (1.9.4 ) has ` uasyncio ` implemented as a
78
+ The current MicroPython release build (1.10 ) has ` uasyncio ` implemented as a
67
79
frozen module. The following options for installing ` fast_io ` exist:
68
80
69
81
1 . Use a daily build, install ` uasyncio ` as per the tutorial then replace the
@@ -75,33 +87,43 @@ frozen module. The following options for installing `fast_io` exist:
75
87
bytecode. If this is deleted and appended to the end, frozen files will only
76
88
be found if there is no match in the filesystem.
77
89
90
+ ``` python
91
+ import sys
92
+ sys.path.append(sys.path.pop(0 )) # Prefer modules in filesystem
93
+ ```
94
+
78
95
See [ ESP Platforms] ( ./FASTPOLL.md#6-esp-platforms ) for general comments on the
79
96
suitability of ESP platforms for systems requiring fast response.
80
97
81
98
## 1.1 Benchmarks
82
99
83
- The benchmarks directory contains files demonstrating the performance gains
84
- offered by prioritisation . They also offer illustrations of the use of these
85
- features. Documentation is in the code.
100
+ The following files demonstrate the performance gains offered by prioritisation
101
+ and the improvements to task cancellation and timeouts . They also show the use
102
+ of these features. Documentation is in the code.
86
103
104
+ Tests and benchmarks to run against the official and ` fast_io ` versions:
87
105
* ` benchmarks/latency.py ` Shows the effect on latency with and without low
88
106
priority usage.
89
107
* ` benchmarks/rate.py ` Shows the frequency with which uasyncio schedules
90
108
minimal coroutines (coros).
91
109
* ` benchmarks/rate_esp.py ` As above for ESP32 and ESP8266.
110
+ * ` fast_io/ms_timer.py ` An I/O device driver providing a timer with higher
111
+ precision timing than ` wait_ms() ` when run under the ` fast_io ` version.
112
+ * ` fast_io/ms_timer_test.py ` Test/demo program for above.
113
+ * ` fast_io/pin_cb.py ` An I/O device driver which causes a pin state change to
114
+ trigger a callback. This is a driver, not an executable test program.
115
+ * ` fast_io/pin_cb_test.py ` Demo of above driver: illustrates performance gain
116
+ under ` fast_io ` .
117
+
118
+ Tests requiring the current version of the ` fast_io ` fork:
92
119
* ` benchmarks/rate_fastio.py ` Measures the rate at which coros can be scheduled
93
120
if the fast I/O mechanism is used but no I/O is pending.
94
- * ` benchmarks/call_lp.py ` Demos low priority callbacks.
121
+ * ` benchmarks/call_lp.py ` Demo of low priority callbacks.
95
122
* ` benchmarks/overdue.py ` Demo of maximum overdue feature.
96
123
* ` benchmarks/priority_test.py ` Cancellation of low priority coros.
97
- * ` fast_io/ms_timer.py ` Provides higher precision timing than ` wait_ms() ` .
98
- * ` fast_io/ms_timer_test.py ` Test/demo program for above.
99
- * ` fast_io/pin_cb.py ` Demo of an I/O device driver which causes a pin state
100
- change to trigger a callback.
101
- * ` fast_io/pin_cb_test.py ` Demo of above.
102
-
103
- With the exceptions of ` call_lp ` , ` priority ` and ` rate_fastio ` , benchmarks can
104
- be run against the official and priority versions of usayncio.
124
+ * ` fast_io/fast_can_test.py ` Demo of cancellation of paused tasks.
125
+ * ` fast_io/iorw_can.py ` Cancellation of task waiting on I/O.
126
+ * ` fast_io/iorw_to.py ` Timeouts applies to tasks waiting on I/O.
105
127
106
128
# 2. Rationale
107
129
@@ -325,8 +347,8 @@ See [Low priority callbacks](./FASTPOLL.md#35-low-priority-callbacks)
325
347
## 3.3 Other Features
326
348
327
349
Variable:
328
- * ` version ` Contains 'fast_io'. Enables the presence of this version to be
329
- determined at runtime.
350
+ * ` version ` Returns a 2-tuple. Current contents ('fast_io', '0.24'). Enables
351
+ the presence and realease state of this version to be determined at runtime.
330
352
331
353
Function:
332
354
* ` got_event_loop() ` No arg. Returns a ` bool ` : ` True ` if the event loop has
@@ -348,6 +370,8 @@ bar = Bar() # Constructor calls get_event_loop()
348
370
# and renders these args inoperative
349
371
loop = asyncio.get_event_loop(runq_len = 40 , waitq_len = 40 )
350
372
```
373
+ This is mainly for retro-fitting to existing classes and functions. The
374
+ preferred approach is to pass the event loop to classes as a constructor arg.
351
375
352
376
###### [ Contents] ( ./FASTPOLL.md#contents )
353
377
@@ -415,8 +439,8 @@ priority task to become overdue by more than 1s.
415
439
### 3.4.1 Task Cancellation and Timeouts
416
440
417
441
Tasks which yield in a low priority manner may be subject to timeouts or be
418
- cancelled in the same way as normal tasks. See [ Task cancellation] ( ./TUTORIAL.md#36 -task-cancellation )
419
- and [ Coroutines with timeouts] ( ./TUTORIAL.md#44 -coroutines-with-timeouts ) .
442
+ cancelled in the same way as normal tasks. See [ Task cancellation] ( ./TUTORIAL.md#521 -task-cancellation )
443
+ and [ Coroutines with timeouts] ( ./TUTORIAL.md#522 -coroutines-with-timeouts ) .
420
444
421
445
###### [ Contents] ( ./FASTPOLL.md#contents )
422
446
@@ -468,22 +492,27 @@ Support was finally [added here](https://github.com/micropython/micropython/pull
468
492
469
493
# 6. Performance
470
494
471
- This version is designed to enable existing applications to run without change
472
- to code and to minimise the effect on raw scheduler performance in the case
473
- where the added functionality is unused.
495
+ The ` fast_io ` version is designed to enable existing applications to run
496
+ unchanged and to minimise the effect on raw scheduler performance in cases
497
+ where the priority functionality is unused.
498
+
499
+ The benchmark ` rate.py ` measures the rate at which tasks can be scheduled;
500
+ ` rate_fastio ` is identical except it instantiates an I/O queue and a low
501
+ priority queue. The benchmarks were run on a Pyboard V1.1 under official
502
+ ` uasyncio ` V2 and under the current ` fast_io ` version V0.24. Results were as
503
+ follows:
474
504
475
- The benchmark ` rate.py ` measures the rate at which tasks can be scheduled. It
476
- was run (on a Pyboard V1.1) under official ` uasyncio ` V2, then under this
477
- version. The benchmark ` rate_fastio ` is identical except it instantiates an I/O
478
- queue and a low priority queue. Results were as follows.
505
+ | Script | Uasyncio version | Period (100 coros) | Overhead | PBD |
506
+ | :------:| :----------------:| :------------------:| :--------:| :---:|
507
+ | rate | Official V2 | 156μs | 0% | 123μs |
508
+ | rate | fast_io | 162μs | 3.4% | 129μs |
509
+ | rate_fastio | fast_io | 206μs | 32% | 181μs |
479
510
480
- | Script | Uasyncio version | Period (100 coros) | Overhead |
481
- | :------:| :----------------:| :------------------:| :--------:|
482
- | rate | Official V2 | 156μs | 0% |
483
- | rate | fast_io | 162μs | 3.4% |
484
- | rate_fastio | fast_io | 206μs | 32% |
511
+ The last column shows times from a Pyboard D SF2W.
485
512
486
513
If an I/O queue is instantiated I/O is polled on every scheduler iteration
487
514
(that is its purpose). Consequently there is a significant overhead. In
488
515
practice the overhead will increase with the number of I/O devices being
489
516
polled and will be determined by the efficiency of their ` ioctl ` methods.
517
+
518
+ Timings for current ` fast_io ` V0.24 and the original version were identical.
0 commit comments