#I mean the plain PulseIn
1 messages · Page 1 of 1 (latest)
if I'm understanding correctly, you mean that while some of pulseio.Pulsein might reuse C-level *buffers, but there's no guarantee they all do.
no, I'm only talking about PulseIn. not the irremote stuff. I thought you were working with servos
For pulseio.PulseIn implementations that do appear to allocate buffers once per PulseIn construction internally, like the espressif version, should you be able to repeatedly call popleft, etc on them without leaving temporaries?
sorry, I tend to juggle a bit - I've got two related but different "open questions" - one related to "reading" servo style PWM signals ("give me duty_cycle" - probably going to try just using ADC / analog inputs), the other regarding the GC footprint of adafruit_irremote. Both involve pulesio.PulseIn, but the GC related focus is specific to adafruit_irremote.
TL;DR; trying to determine whether most boards can at least read the PulseIn data without leaving stranded temporaries - because if that's true then taking a crack at a low-no GC temporary reimplementation of adafruit_irremote (with a different name) would make more sense
ESP's PulseIn looks like it allocates on object construction only
that's what it looked like to me
have you used memorymonitor to find hidden allocations?
but I haven't even run (much less looked at the source for) CircuitPython on anything other than ESP32 variants
I've been using various patterns for before/after sampling with gc.mem_alloc() and gc.mem_free()
Haven't nailed down everything, but it's been enough to find the "worst offenders"
unfortunately that includes passing in *variadic, **andKeyword parameters on function/method invocations - took a good bit of refactoring to deal with those (fortunately there's no cost invoking functions which optionally accept such parameters when you don't pass any in)
But the "big bad" for chewing through GC like candy have been adafruit_irremote and adafruit_httpserver (and dealing with JSON encoding for websocket packets)
Unfortunately both of those are quite a bit more useful for my target audience then reading servo style PWM so they can recycle old RC transmitter/receiver pairs
memorymonitor is meant to let you assert a section of code doesn't trigger any allocations
I'd guess mem_alloc and mem_free are only accurate after a collect
mem_alloc and mem_free look to be mostly accurate. I've built a bunch of bench test code to isolate very specific repetitive behaviors and I get statistically consistent results. There is occasional weirdness, but I suspect that's due to various sporadic background stuff.
specifically, if before / after gc.mem_free() samples around a given "behavior" like foo(a,b,**kwds) shows a net drop, 100 calls will show 100 more similar drops and a gc.collect() at the end gets it all back
I haven't done much with garbage collection prior to CircuitPython - it tends to be a major no-no in most of my "professional" work because of latency issues. Since minimizing latency is more important than overall performance in some embedded stuff and pretty much anything related to automated trading, if you need dynamic allocation at all it's usually done on the heap with reference counting, to avoid unpredictable delays from the garbage collector jumping in. Even then, there's still a lot of monkey business trying to get things optimally situated for alignment and cache sizes (usually several layers in big multi-processing servers (with multiple cores in multiple cpus), locality to minimize page swapping.... can trap one in serious techno-navel-gazing
Because of that background, I've got a lot of experience with stupid reference counting tricks and C/C++ heap implementations. My C++ ESP32 firmware has a totally custom heap system which I can tune based on allocation size and (optionally) track the "stack" responsible for every allocation with surprisingly low overhead. And it can manage all kinds of fun stuff - including serious websocket traffic, managing a local LVGL interface with a touchpanel TFT and some snazzy StemmaQT inputs ( the quad Encoder and the "Navigator") , running local DSL code, and driving over 1000 NeoPixels (7 channels of 150 each) fast enough to never notice a refresh without "leaking" memory for weeks at a time. What's your Christmas tree look like 😁 ?