-
Notifications
You must be signed in to change notification settings - Fork 13.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SPIFFS file access slow on 16/14M flash config #5932
Comments
It may be time for LittleFS ? |
@d-a-v I guess so, but for the project I meant to use it for I have to make a choice on file system in the next few weeks. (2 months at most) |
Does anyone have a suggestion how I can increase the block size of this partition layout? In
Original is: Arduino/tools/sdk/ld/eagle.flash.16m14m.ld Lines 17 to 20 in 68c0a1c
|
Known issue: File access on 16M14M config is quite slow, probably due to high number of blocks in the filesystem. See: esp8266/Arduino#5932
The slowness you describe is known and reported in #2581 . However, I'll keep this open to address the specifics of performance, given that the other thread has grown too long. |
I have tried several builds myself but keep running into crash/reboot loops when trying to set the block size to 32kB. For my own project, I will try to use the left over 12 MB of flash (using the 4M/1M config) as a single circular buffer and thus also avoid any other SPIFFS issue I may run into. |
How about testing with bigger page size in the meantime? The impact of page size is also not known. |
The underlying SPIFFS lib isn't ours, it comes from here: Docs are in their wiki. |
The .ld files are also from the spiffs project? |
Known issue: File access on 16M14M config is quite slow, probably due to high number of blocks in the filesystem. See: esp8266/Arduino#5932
Known issue: File access on 16M14M config is quite slow, probably due to high number of blocks in the filesystem. See: esp8266/Arduino#5932
@d-a-v Can you use FTP with Little FS in the usual fashion? |
@bill-orange |
@bill-orange you can probably run the same FTP server library,. but if it hardcodes |
@TD-er, I don't have a 16M board but would be interested in hoe LittleFS V2 works with it and the settings used. Would you be able to run your testing w/LittleFS instead and report some results? We kind of assume it'll be better than SPIFFS, but hard data is way better... |
Sure, if you show me how to build it, I can test it. |
In your git tree it's pretty simple to do a branch (change upstream to origin if you're working off a clone of the master git and not a private fork):
From then on, just search-and-replace SPIFFS with LittleFS (headers, SPIFFS.open, most likely only places). |
Oh, and of course you lose all data in flash since it's a different FS. If there's something critical on the board, don't do this... |
Ofcourse tests will be done on non remote nodes that do not need stairs and screwdrivers to reach :) |
I prepared the framework like you explained and did a query replace on the SPIFFS to LittleFS like this:
But I get errors like these:
So apparently I still need something defined somewhere?
|
Ah, adding I will now upload it and start testing. |
Thanks, looks like we cross posted. |
OK, first conclusion: Other pages show just a bit faster load times compared to the 1M SPIFFS, but at least not slower. Saving some update to the settings file does take quite a bit more time (1.8 sec for updating part of a file)
I will now include my new "cache controller", which does lots of appends to a file, to see how that will perform. |
One thing that's not looking right.
Edit: |
This "Cache Controller" is some controller collecting samples with 24 bytes in total per sample.
Garbage Collection after deleting 24 files of 24k from full SPIFFS filesystem:
Apparently there is no garbage collection on LittleFS? About the free space. It seems like I'm computing the amount of used space.???? |
For those who want to test. In the RAR file is also a basic settings file, which you can copy to the filesystem after you setup the WiFi credentials etc. On 1M SPIFFS I could store about 23 or 24 of these files. The rest was overhead due to filesystem fragmentation. Edit: |
Thanks, @TD-er ! I just pushed a fix to the PR for the free space reporting, thanks for catching it. There's no GC for LittleFS, at least not externally accessible by a user of the FS. It's not using the NOR specific tricks that SPIFFS is, so I think a lot of design decisions were different. Can you give an idea of what SaveFile is doing? If it's really as bad as it looks, we can post something to the LittleFS repo (assuming I can develop a test case to reproduce it, that is). >1second seems like it should have WDT'd since I have neither yield() or delay() in the library. |
The WDT's are at 2 sec for the SW watchdog and 6 sec for the HW watchdog. And I will have a look at it tomorrow to see what's wrong there. Also I must take a look at the file upload. That's horribly slow and uploading a file > 3 MB is not possible. The connection is reset before it may finish. But first I must take some sleep. It's already past midnight here. Do you have plans to make this somewhat selectable using a define, to make the switch from SPIFFS to LittleFS more dynamic? And on a side note. If you plan on buying 16MB nodes, do not trust the power regulators on them. |
Hmm, indeed. |
I've had it running over night and got some statistics for the cache controller (appending to files)
Those extremes are quite large and also the average seems quite high, which may indicate the extremes do occur more than once. Last night I did fill up the flash completely and deleted the dummy files again. So it may need to do some garbage collection which may stall the process. This test node was only running the sysinfo plugin (4x each second) and writing it to the cache controller, so there's no network activity involved. It has written 3632 kB in bursts of 240 bytes. It seems like the file handling becomes slower when there are more files present. |
I made some changes to write in blocks instead of per byte, but the time needed to save the settings is the same.
The updates are in a bigger file.
So the save function does write it all in 1 burst. |
LittleFS can be built in custom 16M build env. See esp8266/Arduino#5932
@TD-er Would it be fair to say that if I wanted to simulate this without ESPEasy I could do a sequence like:
If that's the case, then it's easy to make a little test case we can try w/the LittleFS object and plain LittleFS on the host to see WTH it's doing. |
No, it does also do a seek into the file itself.
N.B. in ESPeasy the current code does write per byte and checks the result, which is rather silly. |
Writing 1,228 bytes, one at a time (i.e. 1228 f.write(char)) is gonna hurt no matter what and, depending on the data durability guarantees, result in up to 1,228 flash sector erases, writes, and verifies. The LittleFS program write buffer is 64 bytes (IIRC) so it might only be a more reasonable ceil(1228/64) = 20, but it's still about 19x more than would be preferable and there's still the overhead of 1K calls through a couple layers of indirection. I don't think you can optimize that much. However, you said you'd tried larger blocks but didn't see a difference:
The code as I now understand it would be
|
I was able to reproduce this with the sketch below, and it is actually a LittleFS design choice. Basically in-the-middle updates require re-writing the blocks after the modified block. On a 64K file with 8K offset, that's 56K x # of blocks (6 in this case I think). You can make it a little faster by handling the copying yourself (see code below, probably has bugs but it's just for demonstration). (From 1.4s to 1.0s) Or, you can use separate files (or a suibdir since they work fine on LittleFS) for each structure and then just overwrite the file-per-structure and you'll have blazing speeds.
|
I think I can make it a separate handler on LittleFS and write a separate import/export handler for it to make it look like a single file. What is the default block size used in LittleFS? Can LittleFS handle concatenation to a file well? |
Append is fine and very fast. It's just updates in the middle of a file that hurt. The LittleFS speed test, for example, is 100s of KB/second writing to the initial test file. Block sizes are the same as SPIFFS, it uses the same options passed in from the IDE. |
Closing as a won't-fix due to SPIFFS being deprecated. LittleFS does have quirks, but is actively supported and many times faster (except for the update-in-middle scenario here). |
Basic Infos
Platform
Settings in IDE
Problem Description
Open file from SPIFFS is quite a bit slower when using 16M/14M flash layout, compared to the same code running on the same node with 4M/1M as flash layout.
I am running a test setup on ESPeasy using the full 16M flash and thus 14M SPIFFS (want to keep using OTA).
Serving any web page is notably slower (1.7 sec compared to 300 msec).
After some debugging, it became clear that opening files from the SPIFFS was taking a lot longer.
And indeed, I do some checks for files on the SPIFFS while serving the web pages.
These checks are not really that efficient (try open instead of check first if it exists), so I will change that.
But still the access times to the SPIFFS are significantly slower when using 16M flash.
In PlatformIO I use:
This behaves the same when using
board = d1_mini_pro
as suggested hereThese are the detected flash settings:
It is apparently using these settings:
Arduino/tools/sdk/ld/eagle.flash.16m14m.ld
Lines 17 to 20 in 3877914
I have not yet tested to see if performance improves when increasing the block size.
Increasing
SPIFFS_MAX_OPEN_FILES
to 20 doesn't seem to make any difference. (was hoping the FD cache would also increase)Or maybe any other tweak suggestions here?
The text was updated successfully, but these errors were encountered: