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
Settings FS: Duplicate finding is extremely slow when dealing with larger number of settings entries #34554
Comments
@optical-o, indeed 60s seems like a long boot time. However it is not possible to reduce the load time without introducing a lot of wear in flash. When settings save is called it will only save something when it is changed, that is why a save will take a longer time. The result of the save will be a file that contains multiple items for the same settings entry. Loading the setting will need to go trough the complete file to find the latest written value. If this is not done older values will be restored. So it is not possible to disable the duplicate settings checking during load. The load time can be reduced by creating a new file with settings from each settings store, but this increases flash wear. Another way to avoid this would be to process the settings file from the end to the start, but even in this case the settings_load would need to process the whole file. Processing from the end to the start could reduce the settings load subtree (but only in the case it needs to load ONE setting, when multiple settings need to be restored from a subtree it is needed to process the complete file). To reduce the boot time the best approach is to reduce the number of calls to settings_load. To do this it would be best if a subsystem (bt) does not call settings_load, but the loading is delayed until everything is setup to call the settings_load one time from the application. |
@optical-o Can you give some more details on backends you have been testing and the flash device that you use? |
I'm using nrf9160 chip with 16Mbit macronix flash - MX25 clocked at 8Mhz.
I understand that the wear on the flash is significant, however i think that settings changing is very rare occasion for most of the devices. The loading is done during every boot sequence, which is much critical part of the settings implementation and should be as quick as possible. |
Regarding my Runtime storage it is simple array containing the settings, key and value. I have some macros to help me with the table definitions.
Each table is defined as its own subtree. |
Which file system do you have mounted at |
I have mounted littlefs with configuration:
prj.conf - CONFIG_FILE_SYSTEM_LITTLEFS with other default settings. I have tried to increase some ram buffers for the littlefs in hope of caching the file inside the memory to decrease the boot time with no luck. The Cache options had little or no effect on the load time. |
Unfortunately, that is not true, in bt-mesh application every (received) communication requires storing data for replay protection, this is done using settings. The flash wear would be unacceptable.
That is also questionable, the critical part is the storage where you would like to make sure that you have stored the data when a unforeseen power failure happens.
I agree that 20s is really bad, I have no experience with littlefs but this seems very slow. In your use case the worst condition that could appear is that it has to proces 60 + 59 + 58 + ... + 1 = 30 * 30.5 = 915 line reads (this is theoretical), resulting in about 20ms per line read. Maybe @de-nordic has more experience with this. To reduce the loading time you could reduce the number of lines in the file before compacting happens. If you would set it equal to the number of parameters you would like to store you would create a new file for every store and achieve the behaviour you are trying to get. |
@optical-o, BTW you are not by accident or intentionally calling a save settings during the loading ? |
I have check again to be sure, but no. I tested if i omit call inside settings_fs: settings_file_load_priv. Currently i added to my code option CONFIG_SETTINGS_FS_NO_DUP which disables the settings_file_check_duplicate call.
And in save function clears the whole file. This is only temporary solution for now. I'm missing indication that something in settings changed so that i know if i have to call settings_save when the device is turning off. So now the file is clear every time device turns off, which is no means ideal. |
@optical-o, could you test again with only disabling the check duplicate during settings_file_load_priv(). I am wondering if something is failing in the check_duplicate(). |
Can you also check the settings subsystem performance with other backend (nvs for example?) |
I will try to create some sample demonstrating. However it will be probably next week due to some deadlines i have to meet. |
@optical-o could you please provide the sample so we can look into this? |
@carlescufi, @de-nordic, @optical-o, maybe this is related to |
@Laczen could be, yes. @optical-o please update based on the feedback above. |
This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time. |
Issues are:
These changes changed saving time from 14s->200ms. |
@optical-o, could you create a PR with the proposed changes ? How do you guarantee that after a settings_save has been succesfully performed that a reboot contains the updated values ? |
The csi_save_end will close the file and flush the value. When settings_save finishes then the values will be in the flash. If the reboot occurs during function call of settings_save before the csi_save_end the data will be lost. |
The settings backends are trying to save write/erase cycles by storing duplicate settings entries and later resolving their duplicates by using the latest entry.
It should also include duplicate free storing and loading settings from memory. (Overwriting the whole settings when saving) The loading would be much faster then loading. Or at-least it should not resolve duplicates when loading the settings when it is resolved when saving it.
When settings reaches 30-60 options the duplicate resolution reaches nearly 10s of loading time. This process can be repeated multiple times if user is using settings_load_subtree due to some limitation such as loading bt settings before application settings.
I have been able to change boot time in my application from 60s to 5s by disabling the duplicate checking during settings load.
I had 2x settings_load_subtree and single settings_load.
The text was updated successfully, but these errors were encountered: