Open dhalbert opened 4 years ago
@kevinjwalters were you using the .py or the .mpy version of the CLUE library?
.mpy
and a slightly old one - it's from adafruit-circuitpython-bundle-5.x-mpy-20200327
This is telling, it's something to do with the evaluation of the result in the argument to a function or specifically to print
.
Press any key to enter the REPL. Use CTRL-D to reload.
Adafruit CircuitPython 5.3.0 on 2020-04-29; Adafruit CLUE nRF52840 Express with nRF52840
>>> from adafruit_clue import clue
>>> import time, gc, random
>>> gc.collect() ; gc.mem_free()
89872
>>> a=[(1.0, 2.0, 3.0) for x in range(500)
... ]
>>> gc.collect() ; gc.mem_free()
71648
>>> read(500)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'read' is not defined
>>> def read(n):
... for idx in range(n):
... a[idx] = clue.magnetic
...
...
...
>>> read(500)
>>> gc.collect() ; gc.mem_free()
71504
>>> read(500)
>>> gc.collect() ; gc.mem_free()
71504
>>> read(500)
>>> gc.collect() ; gc.mem_free()
71504
>>> t1 = time.monotonic_ns() ; read(500) ; t2 = time.monotonic_ns()
>>> t1-t2
-1782595000
>>> (t1-t2)/1e9
-1.78259
>>> res = (t1-t2)/1e9
>>> print(res)
-1.78259
>>> print((t1-t2)/1e9)
MemoryError: memory allocation failed, allocating 512 bytes
It's got weirder, following on from commands in previous comment:
>>> t1-t2
-1782595000
>>> print(-1782595000/1e9)
-1.78259
>>> print(t1/1e9)
18424.0
>>> print((t1-t2)/1e9)
MemoryError: memory allocation failed, allocating 512 bytes
>>> print((t1+t2)/1e9)
MemoryError: memory allocation failed, allocating 512 bytes
>>> print(t1/1e9 - t2/1e9)
-1.78125
>>> print((t1-t2)/1e9)
MemoryError: memory allocation failed, allocating 512 bytes
There's something about brackets that it doesn't like
Adafruit CircuitPython 5.3.0 on 2020-04-29; Adafruit CLUE nRF52840 Express with nRF52840
>>>
>>>
>>> from adafruit_clue import clue
>>> import time, gc, random
>>> gc.collect() ; gc.mem_free()
91824
>>> a=[(1.0, 2.0, 3.0) for x in range(500)]
>>> gc.collect() ; gc.mem_free()
73616
>>> def read(n):
... for idx in range(n):
... a[idx] = clue.magnetic
...
...
...
>>> t1 = time.monotonic_ns() ; read(500) ; t2 = time.monotonic_ns()
>>> gc.collect() ; gc.mem_free()
73024
>>> print((t1-t2)/1e9)
-1.8214
>>> t1 = time.monotonic_ns() ; read(500) ; t2 = time.monotonic_ns()
>>> print((t1-t2)/1e9)
MemoryError: memory allocation failed, allocating 512 bytes
>>> gc.collect() ; gc.mem_free()
72992
>>> print((t1-t2)/1e9)
MemoryError: memory allocation failed, allocating 512 bytes
>>> var1=t1+t2
>>> var2=(t1+t2)
>>> var3=((t1+t2))
MemoryError: memory allocation failed, allocating 512 bytes
>>> var4=(1,2,3,4,5,6,7,8,10,11,12,13,14)
>>> var5=(t1, t2)
>>> var6=((t1+t2))
MemoryError: memory allocation failed, allocating 512 bytes
Retested with 8.2.7 and latest libraries. It fails even earlier:
Adafruit CircuitPython 8.2.7 on 2023-10-19; Adafruit CLUE nRF52840 Express with nRF52840
>>> from adafruit_clue import clue
>>> import time, gc, random
>>> gc.collect() ; gc.mem_free()
87200
>>> a=[(1.0, 2.0, 3.0) for x in range(500)
... ]
>>> def read(n):
... for idx in range(n):
... a[idx] = clue.magnetic
...
...
...
>>>
>>>
>>> gc.collect() ; gc.mem_free()
68800
>>> read(500)
>>> gc.collect() ; gc.mem_free()
68832
>>> read(500)
>>> gc.collect() ; gc.mem_free()
MemoryError: memory allocation failed, allocating 384 bytes
>>> read(500)
MemoryError: memory allocation failed, allocating 384 bytes
I've debugged this. It is a pathological case where the .magnetic
code takes a couple allocations and then creates the tuple that is stored in a
. This leaves short gaps between each tuple that is held for longer.
Below is the output of gc_dump_alloc_table()
for the last memory pool when the memory allocation fails. Each character is a block. T
is tuple, =
continues the object and .
is free. It is severely fragmented.
I think this only happens from the REPL because the compilation process that runs the input has larger allocations than can fit. When the code is in a file, that cost is paid up front before this code is run.
GC memory layout; from 0x20028760:
00000000: ..............T=..................T=..................T=........
00000400: ..........T=..................T=...............T=..........T=...
00000800: .......T=.............T=.........T=..........T=..........T=.....
00000c00: ........T=.........T=..........T=..........T=.............T=....
00001000: .....T=..........T=..........T=.............T=.........T=.......
00001400: ...T=..........T=.............T=.........T=..........T=.........
00001800: .T=.............T=.........T=..........T=..........T=...........
00001c00: ..T=.........T=..........T=..........T=.............T=.........T
00002000: =..........T=..........T=.............T=.........T=..........T=.
00002400: .........T=.............T=.........T=..........T=..........T=...
00002800: ..........T=.........T=.......h....h=.h==h..T=.........T=T=.....
00002c00: .....T=..T=......T=T=........T=T=......T=..T=....T=....T=..T=...
00003000: ...T=T=........T=T=......T=..T=....T=....T=..T=......T=T=.......
00003400: .T=T=......T=..T=....T=....T=..T=......T=T=........T=T=......T=.
00003800: .T=....T=....T=..T=......T=T=........T=T=......T=..T=....T=....T
00003c00: =..T=......T=T=........T=T=......T=..T=....T=....T=..T=......T=T
00004000: =........T=T=......T=..T=....T=....T=..T=......T=T=........T=T=.
00004400: .....T=..T=....T=....T=..T=......T=T=........T=T=h=hh=hT=h======
00004800: =T=h=......T=........T=........T=........T=........T=........T=.
00004c00: .......T=........T=........T=........T=........T=........T=.....
00005000: ...T=........T=........T=........T=........T=........T=........T
00005400: =........T=........T=........T=........T=........T=........T=...
00005800: .....T=........T=........T=........T=........T=........T=.......
00005c00: .T=........T=........T=........T=........T=........T=........T=.
00006000: .......T=........T=........T=........T=........T=........T=.....
00006400: ...T=........T=........T=........T=........T=........T=........T
00006800: =........T=........T=........T=........T=........T=........T=...
00006c00: .....T=........T=........T=........T=........T=........T=.......
00007000: .T=........T=........T=........T=........T=........T=........T=.
00007400: .......T=........T=........T=........T=........T=........T=.....
00007800: ...T=........T=........T=........T=........T=........T=........T
00007c00: =........T=........T=........T=........T=........T=........T=...
00008000: .....T=........T=........T=........T=........T=........T=.......
00008400: .T=........T=........T=........T=........T=........T=........T=.
00008800: .......T=........T=........T=........T=........T=........T=.....
00008c00: ...T=........T=........T=........T=........T=........T=........T
00009000: =........T=........T=........T=........T=........T=........T=...
00009400: .....T=........T=........T=........T=........T=........T=.......
00009800: .T=........T=........T=........T=........T=........T=........T=.
00009c00: .......T=........T=........T=........T=........T=........T=.....
0000a000: ...T=........T=........T=........T=........T=........T=........T
0000a400: =........T=........T=........T=........T=........T=........T=...
0000a800: .....T=........T=........T=........T=........T=........T=.......
0000ac00: .T=........T=........T=........T=........T=........T=........T=.
0000b000: .......T=........T=........T=........T=........T=........T=.....
0000b400: ...T=........T=........T=........T=........T=........T=........T
0000b800: =........T=........T=........T=........T=........T=........T=...
0000bc00: .....T=........T=........T=........T=........T=........T=.......
0000c000: .T=........T=........T=........T=........T=........T=........T=.
0000c400: .......T=........T=........T=........T=........T=........T=.....
0000c800: ...T=........T=........T=........T=........T=........T=........T
0000cc00: =........T=........T=........T=........T=........T=........T=...
0000d000: .....T=........T=........T=........T=........T=........T=.......
0000d400: .T=........T=........T=........T=........T=........T=........T=.
0000d800: .......T=........T=........T=........T=........T=........T=.....
0000dc00: ...T=........T=........T=........T=........T=........T=........T
0000e000: =........T=........T=........T=........T=........T=........T=...
0000e400: .....T=........T=........T=........T=........T=........T=.......
0000e800: .T=........T=........T=........T=........T=........T=........T=.
0000ec00: .......T=........T=........T=........T=........T=........T=.....
0000f000: ...T=........T=........T=........T=........T=........T=........T
0000f400: =........T=........T=........T=........T=........T=........T=...
0000f800: .....T=........T=........T=.
Thanks for looking into that.
I think this started because I wanted to see what rate I could read at and how close I could get to the sensor's maximum rate. I think there are some other recent efforts afoot for bulk sampling or continuous sampling of sensors perhaps via DMA where the hardware permits? Had to look this up, I'm thinking of analogbufio. Is there anything afoot for something similar with an interrupt driving approach for i2c with nRF52 for my scenario?
Is there anything afoot for something similar with an interrupt driving approach for i2c with nRF52 for my scenario?
Not yet. But I could see us adding something like that to "read X register N times over i2c".
from @kevinjwalters: https://forums.adafruit.com/viewtopic.php?f=60&t=165359 (this example from second post in that thread)