Replies: 5 comments 2 replies
-
Interesting! When I run This is somewhat related to your post and may be of interest: I found that with the ESP32 and a large flash, the the Littlefs2 filesystem has a parameter that can speed up things a bit, see https://docs.micropython.org/en/latest/library/os.html os.VfsLFs2() I do the following at the beginning of main.py:
For me, this speeds up some file operations by a factor of 2 or 3 on the ESP32-N8R8. YMMV. The Also, the optimal value for lookahead is the number of flash blocks divided by 8, with a modest impact on write performance. The lookahead buffer is a bitmap of free blocks. After writing 32*8 blocks, LittleFS2 has to fill up the lookahead buffer again, since there is no free block bitmap on flash. So a large lookahead buffer avoids reconstructing this bitmap. I didn't see any impact of the This may also be of interest: writing small files (less than 1024 bytes on the ESP32) writes data to the directory structure instead of using dedicated data blocks and is quite fast. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
One thing that makes writes slow on ESP32 is that it only writes in 64 byte chunks! You can set If sectors are erased immediately before being written, then sector erase time dominates and this doesn't matter so much that it goes through multiple buffers, because each layer doesn't know that the layer under also buffers, and so they get away with this inefficiency. A faster system would pre-erase blocks when idle to have a pool ready so when writes do occur they don't suffer from the erase time. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
I added support for external QSPI flash chips via ESP-IDF. And it seems slow. I can't find any sort of benchmarks for flash speed on ESP32s. Just nothing at all. So I benchmarked the built-in flash, and it seems slow too.
I wrote a filesystem benchmark that is meant to be somewhat like a data logging program. It appends chunks of data to a file until the file gets to be large, the opens another file, and so on. Then reads them back sequentially.
Here's the result for the onboard flash on an ESP32-S3-MINI-N8R2:
Only 55 kB/sec write speed and about 1 MB/sec read. It's running in quad mode and 80 MHz. I thought it would be a bit faster than that.
For comparison, here is the external flash, using basically the same code in ESP-IDF (but not really, since the onboard flash is made by gd and the external is mcix and each flash driver in esp-idf is separate code, even though they should be 99% identical, they aren't).
Double the write speed and triple the read speed.
And then for further comparison, I used https://github.com/peterhinch/micropython_eeprom (with a 4kB block size), on the external flash chip.
Somewhat slower.
To get an idea of what the flash could do without a filesystem, I benchmarked it using the
readblocks()
andwriteblocks()
methods directly. I also tried directly reading the entire flash in blocks using the ESP-IDF C API and wrapping that in a single Python function. Here are the results in graphical form.The internal (green) and external flash (purple) in QIO mode are similar speed. The drop-off at a 64kB block size or above is interesting, I suspect that this might be the result of the memory buffer being placed into PSRAM instead of the on chip memory.
Also shown, blue lines, is the external flash in SPI (1-bit) mode. This is slower, but it's interesting to see that the read speed of the python eeprom library is actually faster than the ESP-IDF code! One wonders why the eeprom lib filesystem benchmark is so much slower.
And finally, raw write speed. Since this overwrites flash, I didn't test the onboard flash as I needed that filesystem.
The jump in speed at 64kB block size is probably because the ESP-IDF driver will switch from 4kB sector erase to 64 kB block erase. The EEPROM library doesn't use that command. It's also slower, which I find odd, since it's mostly waiting for the flash to erase. As we can see from how QSPI and SPI modes are basically the same speed.
And finally, the actual code. One can get the flash filesystem partition on an ESP32 with
vfs = esp32.Partition.find(type=1, label="vfs")[0]
, and then pass it toreadbench()
. Probably don't want to do that withwritebench()
unless you make another partition to overwrite, or it will clobber the filesystem.fstest()
will default to writing into/
, but it can be set withpath
argument to another mounted filesystem. It should only write and then delete the test files it makes and leave any others untouched.I'd be interested if others see the same poor speeds as me.
Beta Was this translation helpful? Give feedback.
All reactions