Armadilloフォーラム

eMMCのフラッシュメモリへの書き込みタイミング

masaya_yoshitomi

2024年9月11日 8時53分

Webアプリケーションからの指令を受信し、fputsを使用して文字列をファイルに書込んだり、cpコマンドで特定のファイルを上書きしたりしてemmcに保存する処理を実装しています。
明示的にsyncコマンドを実装してはいません。

少し調べるとdirty_expire_centisecs(データがキャッシュにどれだけの時間残るか:最遅で書込まれる時間)とdirty_writeback_centisecs(定期的にバックグラウンドで未書込みデータを書き込む間隔、頻度)である程度決められるとのことでしたので、今の設定はdirty_expire_centisecs=30秒(デフォルト)、dirty_writeback_centisecs=5秒(デフォルト)になっています。

このとき、fputsやcpを実行してから実際にemmcに書き込まれるまでにかかる時間はどれくらいの誤差があるものでしょうか?
ご教示お願いします。
回答に必要な要素がほかにもありましたらご教示お願いします。

感覚的には、dirty_expire_centisecsのほうは基本的にログファイル用で、dirty_writeback_centisecsがユーザ操作やアプリ処理で実行される保存処理用のようなイメージを持っています。そのあたりの使われ方もあわせてご教示いただけると幸いです。

コメント

溝渕です。

> 少し調べるとdirty_expire_centisecs(データがキャッシュにどれだけの時間残るか:最遅で書込まれる時間)とdirty_writeback_centisecs(定期的にバックグラウンドで未書込みデータを書き込む間隔、頻度)である程度決められるとのことでしたので、今の設定はdirty_expire_centisecs=30秒(デフォルト)、dirty_writeback_centisecs=5秒(デフォルト)になっています。

上記調査されている目的ですが、「ファイルシステムに書いたデータが、xxx秒後にはeMMCに書き込み完了している事を保証したい。」のような事でしょうか? もしそうであれば、syncを明示的に実行してsyncの完了を待つ事をお勧めします。

> このとき、fputsやcpを実行してから実際にemmcに書き込まれるまでにかかる時間はどれくらいの誤差があるものでしょうか?

一般的には不定です。ただ、現実的には数分/数時間かかる事は無いと思われます。

要因は様々あり、
- LinuxはリアルタイムOSではない為、ディスク(eMMC)とディスクキャッシュ(DRAM)を同期するプロセスが実行されるまでの最大時間が定義されない
- 主記憶装置(DRAM)は補助記憶装置(eMMC)よりも早い
などです。

以下のパラメータである程度の調整は可能ですが、
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree…
要件次第ですが、私の推測した目的を完全に達成する事は、パラメータ調整ではできないかと思います。

masaya_yoshitomi

2024年9月11日 10時00分

> 上記調査されている目的ですが、「ファイルシステムに書いたデータが、xxx秒後にはeMMCに書き込み完了している事を保証したい。」のような事でしょうか? もしそうであれば、syncを明示的に実行してsyncの完了を待つ事をお勧めします。
⇒目的は「システムコール実行の最大xx秒後にはeMMCに書き込み完了されている」ということを言いたいです。

> 一般的には不定です。ただ、現実的には数分/数時間かかる事は無いと思われます。
> 要因は様々あり、
> - LinuxはリアルタイムOSではない為、ディスク(eMMC)とディスクキャッシュ(DRAM)を同期するプロセスが実行されるまでの最大時間が定義されない
> - 主記憶装置(DRAM)は補助記憶装置(eMMC)よりも早い
> などです。
>
> 以下のパラメータである程度の調整は可能ですが、
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree…
> 要件次第ですが、私の推測した目的を完全に達成する事は、パラメータ調整ではできないかと思います。
>
⇒fcloseでファイルバッファをeMMCに書き込むことにならないでしょうか?dirty_writeback_centisecsが"ディスク(eMMC)とディスクキャッシュ(DRAM)を同期するプロセス"と思っていましたが違うということでしょうか?実際の動作を見ても数分もかかっていないとは思っています。

溝渕です。

> ⇒目的は「システムコール実行の最大xx秒後にはeMMCに書き込み完了されている」ということを言いたいです。

上記、先に申し上げました理由により保証する事はできません。

> ⇒fcloseでファイルバッファをeMMCに書き込むことにならないでしょうか?

fclose(3)は内部的にfflush(3)をcallしますが、fflush(3)はユーザー空間バッファーだけをフラッシュします。今回の目的がeMMCへの書き込みですので、fysnc(2)をcallする必要があります。

> dirty_writeback_centisecsが"ディスク(eMMC)とディスクキャッシュ(DRAM)を同期するプロセス"と思っていましたが違うということでしょうか?

いえ、合っています。

正確には、"ディスク(eMMC)とディスクキャッシュ(DRAM)を同期するpdflushというスレッドの起動間隔"です。このスレッドが同期を完了するとディスクとディスクキャッシュが同期されますが、先に申し上げました通り、このスレッドが実際にいつまでに実行されるかは保証されません(LinuxがリアルタイムOSでない)し、同期にかかる時間を固定できない(主記憶装置は補助記憶装置よりも早いのでデータ量に依存してしまう)です。

> 実際の動作を見ても数分もかかっていないとは思っています。

先に申し上げました通り、通常は数分もかかる事は無いと思います。ただ、xxx分/yyy秒以内に完了する事を「保証」できるかというと、上記の理由によりできません。

fsync(2)を発行する事は不可能でしょうか?

masaya_yoshitomi

2024年9月11日 17時12分

> fclose(3)は内部的にfflush(3)をcallしますが、fflush(3)はユーザー空間バッファーだけをフラッシュします。今回の目的がeMMCへの書き込みですので、fysnc(2)をcallする必要があります。
>
> > dirty_writeback_centisecsが"ディスク(eMMC)とディスクキャッシュ(DRAM)を同期するプロセス"と思っていましたが違うということでしょうか?
>
> いえ、合っています。
>
> 正確には、"ディスク(eMMC)とディスクキャッシュ(DRAM)を同期するpdflushというスレッドの起動間隔"です。このスレッドが同期を完了するとディスクとディスクキャッシュが同期されますが、先に申し上げました通り、このスレッドが実際にいつまでに実行されるかは保証されません(LinuxがリアルタイムOSでない)し、同期にかかる時間を固定できない(主記憶装置は補助記憶装置よりも早いのでデータ量に依存してしまう)です。
>
> > 実際の動作を見ても数分もかかっていないとは思っています。
>
> 先に申し上げました通り、通常は数分もかかる事は無いと思います。ただ、xxx分/yyy秒以内に完了する事を「保証」できるかというと、上記の理由によりできません。
>
> fsync(2)を発行する事は不可能でしょうか?
>
fsyncは実行可能ですので検討します。
すみません、「主記憶装置は補助記憶装置よりも早いのでデータ量に依存してしまう」が理解できておりません。
書き込み回数も気になるのですが、書き込み回数の上限はどれくらいでしょうか?

溝渕です。

> すみません、「主記憶装置は補助記憶装置よりも早いのでデータ量に依存してしまう」が理解できておりません。

以下のような意味です。

- 主記憶装置は早いので、書き込み容量が増えても体感的には早く感じる
- 補助記憶装置は遅いので、書き込み容量が増えると体感的に遅くなったように感じる

例えば、電源を入れてから機器が起動するまでの時間が、0.1秒から0.2秒になっても人の感覚だと気にならないと思います。これが、10秒から20秒になると

理解が困難な表現をしてしまいすみません。

> 書き込み回数も気になるのですが、書き込み回数の上限はどれくらいでしょうか?

P/Eサイクル寿命は25,000回です。erase block単位でデータを上書きし続けた場合はeMMCの容量分のデータを25,000回書き込む(正確にはeraseする)事ができます。

masaya_yoshitomi

2024年9月13日 15時03分

> 溝渕です。
>
> > すみません、「主記憶装置は補助記憶装置よりも早いのでデータ量に依存してしまう」が理解できておりません。
>
> 以下のような意味です。
>
> - 主記憶装置は早いので、書き込み容量が増えても体感的には早く感じる
> - 補助記憶装置は遅いので、書き込み容量が増えると体感的に遅くなったように感じる
>
> 例えば、電源を入れてから機器が起動するまでの時間が、0.1秒から0.2秒になっても人の感覚だと気にならないと思います。これが、10秒から20秒になると
>
> 理解が困難な表現をしてしまいすみません。
>
>
> > 書き込み回数も気になるのですが、書き込み回数の上限はどれくらいでしょうか?
>
> P/Eサイクル寿命は25,000回です。erase block単位でデータを上書きし続けた場合はeMMCの容量分のデータを25,000回書き込む(正確にはeraseする)事ができます。
>
寿命に対する考え方をもう少し深堀させてください。
・3.4GBのeMMCの領域に対して25000回書込めるという意味の場合、3.4GB*25000回=85000[GB*回]分の書込める領域があるという理解でよろしいでしょうか?
・G3に搭載されているeMMCのerase block単位は何KB?MB単位でしょうか?
・例えば以下のようなケースの場合、寿命は論理的にどのように減りますでしょうか?
 ①22KBのファイルを上書き保存
 ②350MBのファイルをfopen⇒1レコード分(1KB)をサイクリックに書込み(1行削除、1行追加)⇒fclose
 ③5MBのファイルに対して、都度数行書込み(syslogなどを想定)
22KBのファイルを上書きすることに対して、erase blockが仮に256KBだった場合、1回の書込みで256KB分の寿命が減るものなのか、また1レコード(1KB)の削除、追加の際に消費される寿命など詳細に把握したいです。

溝渕です。

> 寿命に対する考え方をもう少し深堀させてください。
> ・3.4GBのeMMCの領域に対して25000回書込めるという意味の場合、3.4GB*25000回=85000[GB*回]分の書込める領域があるという理解でよろしいでしょうか?

そうですね。eMMC内蔵ファームウェアのウェアレベリングが理想的な動きをするのであれば、上記理解で正しいです。eMMC内蔵ファームウェアの仕様は非公開ですが、あえて非効率な実装をするとも考え難いので、この理解で良いと思います。

実際のところ、弊社でeMMCの全領域に対して10万回を越える書き込みを行った事があるのですが、データ化け等は確認できませんでした。

> ・G3に搭載されているeMMCのerase block単位は何KB?MB単位でしょうか?

512KiBです。

> ・例えば以下のようなケースの場合、寿命は論理的にどのように減りますでしょうか?
>  ①22KBのファイルを上書き保存
>  ②350MBのファイルをfopen⇒1レコード分(1KB)をサイクリックに書込み(1行削除、1行追加)⇒fclose
>  ③5MBのファイルに対して、都度数行書込み(syslogなどを想定)
> 22KBのファイルを上書きすることに対して、erase blockが仮に256KBだった場合、1回の書込みで256KB分の寿命が減るものなのか、また1レコード(1KB)の削除、追加の際に消費される寿命など詳細に把握したいです。

先に述べましたように、eMMC内蔵ファームウェアの仕様が不明ですので何とも言えません。想像になりますが、もし私が実装するとなった場合は、erase回数を最小限に留めたいと考え、書き込みの度にeraseを行って新しい領域に書き込むような実装にはしないと思います。