dancyPi-audio-reactive-led
dancyPi-audio-reactive-led copied to clipboard
LED update performance on Raspberry Pi
Hey!
I've been playing around with this on a raspberry pi for the last few days, and I've spent some time doing some basic profiling, trying to figure out where the performance bottleneck might be. I noticed that the update cycle was falling behind, pretty consistently taking about 0.03 seconds to complete, regardless of what the FPS is set to.
From what I can tell, the main bottleneck is in led.py when setting the strip._led_data values. If you remove the prev_pixels comparison, the led.update function drops from about 0.02 seconds to 0.0075 seconds (so a little over 2.5x faster).
It looks like most of the led code is from the scottlawsonbc repo, and hasn't been touched since its initial commit like 4 years ago. I don't know if there's just been updates to the rpi_ws281x library in that time or what, but I'm honestly not sure what that check is trying to achieve. I'm pretty sure the underlying library would still send update signals to all of the leds in the strip regardless of whether their rgb value has changed.
Hey, sorry missed this thread somehow!
That's a good find! The speed boost you found is amazing.
I think what the check is trying to achieve is skip writing to the LED strip if that particular LED has the same data as before. Since this code is really old, it was probably more efficient on older versions of numpy, ws2812x, python, etc. and probably doesn't make a lot of sense now.
I think it would be fine to remove the check. I have a couple other projects using the rpi_ws281x lib and I don't use a check like that, I just override it with the same value if necessary.
If you want to make the change and do a pull request, feel free, I can test it and pull it into my project. You might have to convince the authors in the original repo if you want to do a pull request there too but they might be fine with it.
If you do want to do this, I'd recommend either commenting out the code there and adding a note OR make the commit comment more descriptive.
Again, good find!
How does one achieve this?
It's pretty simple from what I remember.
In led.py, the _update_pi()
function, lines 103-108 is a loop that updates the strip._led_data array. All you need to do is comment out lines 105 and 106, which is the conditional that checks the new led data against the previous values.
So it should look like
for i in range(config.N_PIXELS):
# Ignore pixels if they haven't changed (saves bandwidth)
# if np.array_equal(p[:, i], _prev_pixels[:, i]):
# continue
strip._led_data[i] = int(rgb[i])
The performance gain I saw was from running a strip of 180 leds, so if you're running considerably more than that, your results may vary. I don't have the code I was working with back when I made this comment, so I'm only going based on my memory.
Good luck!