1
1
# fast_io: A modified version of uasyncio
2
2
3
- MicroPython firmware now enables device drivers for stream devices to be
4
- written in Python, via ` uio.IOBase ` . This mechanism can be applied to any
5
- situation where a piece of hardware or an asynchronously set flag needs to be
6
- polled. Such polling is efficient because it is handled in C using
7
- ` select.poll ` , and because the coroutine accessing the device is descheduled
8
- until polling succeeds.
9
-
10
- Unfortunately official ` uasyncio ` polls I/O with a relatively high degree of
11
- latency. It also has a bug whereby bidirectional devices such as UARTS can
12
- fail to handle concurrent input and output.
3
+ This version is a "drop in" replacement for official ` uasyncio ` . Existing
4
+ applications should run under it unchanged and with essentially identical
5
+ performance.
13
6
14
- This version has the following changes :
7
+ This version has the following features :
15
8
* I/O can optionally be handled at a higher priority than other coroutines
16
9
[ PR287] ( https://github.com/micropython/micropython-lib/pull/287 ) .
17
10
* Tasks can yield with low priority, running when nothing else is pending.
18
11
* Callbacks can similarly be scheduled with low priority.
19
- * The bug with read/write device drivers is fixed.
12
+ * A [ bug] ( https://github.com/micropython/micropython/pull/3836#issuecomment-397317408 )
13
+ whereby bidirectional devices such as UARTS can fail to handle concurrent
14
+ input and output is fixed.
15
+ * It is compatible with ` rtc_time.py ` for micro-power applications documented
16
+ [ here] ( ./lowpower/README.md ) .
20
17
* An assertion failure is produced if ` create_task ` or ` run_until_complete `
21
18
is called with a generator function
22
19
[ PR292] ( https://github.com/micropython/micropython-lib/pull/292 ) . This traps
@@ -34,13 +31,8 @@ version.
34
31
The high priority mechanism formerly provided in ` asyncio_priority.py ` was a
35
32
workround based on the view that stream I/O written in Python would remain
36
33
unsupported. This is now available so ` asyncio_priority.py ` is obsolete and
37
- should be deleted from your system.
38
-
39
- The facility for low priority coros formerly provided by ` asyncio_priority.py `
40
- is now implemented.
41
-
42
- This version also provides for ultra low power consumption using a module
43
- documented [ here] ( ./lowpower/README.md ) .
34
+ should be deleted from your system. The facility for low priority coros
35
+ formerly provided by ` asyncio_priority.py ` is now implemented.
44
36
45
37
###### [ Main README] ( ./README.md )
46
38
@@ -61,6 +53,7 @@ documented [here](./lowpower/README.md).
61
53
3.5 [ Low priority callbacks] ( ./FASTPOLL.md#35-low-priority-callbacks )
62
54
4 . [ ESP Platforms] ( ./FASTPOLL.md#4-esp-platforms )
63
55
5 . [ Background] ( ./FASTPOLL.md#4-background )
56
+ 6 . [ Performance] ( ./FASTPOLL.md#6-performance )
64
57
65
58
# 1. Installation
66
59
@@ -104,6 +97,16 @@ be run against the official and priority versions of usayncio.
104
97
105
98
# 2. Rationale
106
99
100
+ MicroPython firmware now enables device drivers for stream devices to be
101
+ written in Python, via ` uio.IOBase ` . This mechanism can be applied to any
102
+ situation where a piece of hardware or an asynchronously set flag needs to be
103
+ polled. Such polling is efficient because it is handled in C using
104
+ ` select.poll ` , and because the coroutine accessing the device is descheduled
105
+ until polling succeeds.
106
+
107
+ Unfortunately official ` uasyncio ` polls I/O with a relatively high degree of
108
+ latency.
109
+
107
110
Applications may need to poll a hardware device or a flag set by an interrupt
108
111
service routine (ISR). An overrun may occur if the scheduling of the polling
109
112
coroutine (coro) is subject to excessive latency. Fast devices with interrupt
@@ -454,3 +457,25 @@ fast scheduling took place
454
457
[ in issue 2664] ( https://github.com/micropython/micropython/issues/2664 ) .
455
458
456
459
Support was finally [ added here] ( https://github.com/micropython/micropython/pull/3836 ) .
460
+
461
+ # 6. Performance
462
+
463
+ This version is designed to enable existing applications to run without change
464
+ to code and to minimise the effect on raw scheduler performance in the case
465
+ where the added functionality is unused.
466
+
467
+ The benchmark ` rate.py ` measures the rate at which tasks can be scheduled. It
468
+ was run (on a Pyboard V1.1) under official ` uasyncio ` V2, then under this
469
+ version. The benchmark ` rate_fastio ` is identical except it instantiates an I/O
470
+ queue and a low priority queue. Results were as follows.
471
+
472
+ | Script | Uasyncio version | Period (100 coros) | Overhead |
473
+ | --- | --- | --- |
474
+ | rate | Official V2 | 156μs | 0% |
475
+ | rate | fast_io | 162μs | 3.4% |
476
+ | rate_fastio | fast_io | 206μs | 32% |
477
+
478
+ If an I/O queue is instantiated I/O is polled on every scheduler iteration
479
+ (that is its purpose). Consequently there is a significant overhead. In
480
+ practice the overhead will increase with the number of I/O devices being
481
+ polled and will be determined by the efficiency of their ` ioctl ` methods.
0 commit comments