了解附加模式下的闪存文件系统磨损
Understanding flash file system wear in append mode
我必须在闪存设备(MMC卡)上写入一个不断增长的日志文件,我担心闪存磨损。
假设我使用fopen
或std::ofsteam::open
以写/附加模式打开日志文件。该文件目前的大小为10MB。如果我只继续追加到文件中,我能保证文件系统不会试图将以前的10MB重新写入新的闪存块吗?
如果这还不清楚,我可以用不同的方式问同样的问题。考虑这个场景:
- 创建一个名为"log.txt"的新文件
- 向文件追加10kB
- 关闭文件
- 其他进程写入同一磁盘/分区上的不同文件
- 重新打开"log.txt"
- 向文件再追加10kB
- 关闭文件
这是否具有与这种情况相同的效果(就闪光磨损而言):
- 创建一个名为"log.txt"的新文件
- 向文件追加20kB
- 关闭文件
大多数闪存文件系统都会内置损耗均衡系统,这样就不会反复使用同一部分闪存。
追加不应该是个问题,因为(我希望)当它存储信息时,写入新数据时不会"磨损"——你只会在"擦除"周期中受到磨损,只有当你删除文件时才会发生这种情况[并且文件所在的扇区需要用新数据重写-如果内容不被替换,那么擦除内容就没有意义]。
为了回答您的实际问题,最好使用附加模式,而不是编写另一个新文件。至少你没有"磨损"文件中已经写入的部分——当涉及到闪存时,碎片应该不会成为问题——访问字节0、1、1000和10000000000000需要完全相同的时间,而不是一个老式的硬盘驱动器,在这种硬盘驱动器中,机械头每隔几次读取就必须移动到下一个数据块,较长的移动需要较长的时间。
如果我只继续追加到文件中,我能保证文件系统不会试图将以前的10MB重新写入新的闪存块吗?
这取决于闪存文件系统。与你的愿望相反,有时重写之前的10MB实际上是件好事。也就是说,执行磨损均衡。每个闪存芯片都有一个扇区和擦除块大小。这些影响了磨损均衡的动态。每个擦除块在一个生命周期内具有最大周期量。如果你的10MB文件几乎是满闪存,那么移动一些扇区是有意义的,这样就可以在那里进行新的擦除。这在wikipedia的磨损平衡页面上被称为静态磨损平衡。
闪存芯片的典型擦除周期为10k-10M。因此,通常情况下,闪存文件系统应级别擦除所有扇区+/-1k内的内容。大多数磁盘都有长期数据和短期数据。希望这能解释移动长寿命数据的必要性。
此外,许多闪存文件系统支持压缩。追加时,应尽量将块保持为扇区大小或压缩块大小的最大值。从C++层,这将自然地缓冲在任务级别的内存中。您可以将流缓冲区大小设置为匹配和/或仅在确定已写入完整扇区时调用flush()
。写入部分扇区(或压缩块)的问题是,这将留下许多部分写入,直到填满完整的擦除块。然后,所有的部分写入都将被擦除。
您不必在应用程序级别注意这一点,但像这样更改日志记录可以显著延长闪存的寿命。当然,一切都在某种程度上取决于闪存文件系统。并非所有这些都会移动静态数据,以确保擦除磨损均衡。它们只能在自由区域上预成型耐磨层;或未使用的闪存空间。
- 文件系统:复制功能的速度秘诀是什么
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 如何传递多个 std::文件系统选项?
- phytec phyBOARD iMX-6在从闪存而不是SD卡运行qt5 opengles应用程序时表现不佳(FPS减半
- 遍历顺序由 std::文件系统directory_iterator给出
- libstdc++ 文件系统中未初始化的用法?
- boost::文件系统::recursive_directory_iterator多线程安全
- C++17 文件系统::remove_all 带有通配符路径
- 实验性文件系统库不完整C++?
- 使用文件系统时仍然需要链接到带有 C++20 的 stdc++fs?
- 无法链接文件系统库C++
- 无法识别 Mac c++ 文件系统库
- 使用Boost文件系统C++将具有特定扩展名的文件的名称保存在特定文件夹中
- 获取 clang++:错误:在编译文件系统库的代码时
- 与SPI NAND闪存(STM32L4,QSPI)的通信问题
- 从不属于应用程序的闪存读取
- LittleFS文件系统,NOR闪存的文件写入问题
- g++arm none eabi从4.9升级到gcc 8.2.生成的二进制文件不再适合闪存
- C++创建文件(紧凑型闪存卡写入器)
- 了解附加模式下的闪存文件系统磨损