Ext4

ext4 文件系統中的文件是否允許持續時間搜尋?

  • January 6, 2022

我正在使用 Tensorflow 的 TFRecords 格式,它將一堆數據點序列化為一個大文件。這裡的典型值是每個數據點 10KB,每個大文件 10,000 個數據點,以及大約 100MB 的大文件。TFRecord 通常只寫一次——它們不會被附加。我認為這意味著它們不會非常分散。

我相信 TFRecords 是基於 Google 的內部 RecordIO 格式。

通常人們在 Ubuntu 18.04 或 20.04 上執行 Tensorflow 和 TFRecords,我認為這通常是一個 ext4 文件系統。

通常,深度學習工程師在 SSD/NVME 磁碟上執行。與 GPU 本身的巨大成本相比,磁性旋轉碟片的成本增量並不重要。

問題一:

在 ext4 文件系統中,如果我知道一個特定的數據點是一個文件中的 9,000,000 字節,我可以尋找到該位置並開始在恆定時間內讀取數據點嗎?恆定時間是指僅作為搜尋深度的函式。我不擔心文件總大小的影響。

如果這是真的,則意味著 ext4 文件系統中的每個文件都有某種查找表/索引,將查找位置映射到磁碟扇區。

幾十年來我沒有看過文件系統,但我似乎記得 FAT 文件系統是鍊錶——你必須讀取一個磁碟扇區才能知道下一個磁碟扇區是什麼。這意味著要在文件中查找 9,000,000 字節,我需要從前 8,999,999 字節中讀取所有磁碟扇區。例如,尋軌時間與尋軌的“深度”成線性關係。我希望 ext4 是恆定的時間,而不是線性的。

問題2:

我的最終目標是對 TFRecord 進行隨機訪問。由於我認為與優化磁性旋轉碟片的讀取速度有關的原因,TFRecords 設計用於串列讀取,而不是隨機訪問。

不管搜尋函式是否是一個常數時間(作為搜尋深度的函式),隨機訪問 ext4 文件系統上的大文件是否“足夠快”?老實說,我不知道什麼是足夠快,但為了簡單起見,假設一個非常快的深度學習模型每秒可能能夠提取 10000 個數據點,其中每個數據點大約 10KB,並且從一個大文件中隨機提取.

也許,如果文件在磁碟上沒有碎片。但如果它是嚴格恆定的時間可能並不重要。

ext2 和 ext3 將數據塊的位置儲存在具有 1 到 4 級的樹中,因此查找不可能是恆定時間的。此外,樹的塊原則上可以位於文件系統的任何位置,因此可能需要進行一些磁碟尋軌。

ext4 儲存一個範圍樹,然後描述多個連續的數據塊。因此,如果已知文件只有一個範圍,則查找將是恆定時間。但如果它是碎片化的(或大於 128 MiB,需要多個擴展區),則不會。

(來源:https ://www.kernel.org/doc/html/latest/filesystems/ext4/dynamic.html#the-contents-of-inode-i-block )

雖然我可能更擔心查找是否足夠快,而不是它們是否是恆定時間。這是一個容易得多的目標,因為無論如何樹都不會太深,如果您重複訪問同一個文件,它們很快就會全部載入到記憶體中,從而消除任何磁碟尋軌(這不是SSD上的一個大問題,但是,無論如何)。每次訪問還有系統呼叫成本,如果您在每次讀/寫之前進行搜尋,則係統呼叫成本會加倍。雖然我認為有一些更高級的系統呼叫可以緩解這種情況。

FAT 文件系統是鍊錶——你必須讀取一個磁碟扇區才能知道下一個磁碟扇區是什麼。這意味著要在文件中查找 9,000,000 字節,我需要從前 8,999,999 字節中讀取所有磁碟扇區。例如,尋軌時間與尋軌的“深度”成線性關係。

FAT 文件系統有一個塊指針表(FAT 表),這些指針形成鍊錶。不是數據塊本身。因此,例如 4 kB 塊大小,您只需要讀取 9000000 / 4096 ~= 2000 個指針,價值幾 kB。儘管如此,它仍然是一個鍊錶,並且迭代它需要與查找位置成比例的一些步驟(除非 fs 驅動程序有一些智能來減少它)。但是 FAT 表是連續的,也可能在記憶體中,因此不涉及磁碟尋軌。

這裡的典型值是每個數據點 10KB,每個大文件 10,000 個數據點,以及大約 100MB 的大文件。

假設一個非常快速的深度學習模型每秒可以提取 10000 個數據點,其中每個數據點大約 10KB 並且從一個大文件中隨機提取。

一個 100 MB 的文件應該很容易完全適合記憶體(多次),並且將其保留在那裡也可以消除搜尋的系統呼叫成本。如果你只是在閱讀,那就是這樣。

如果你也要寫,請注意,不是所有的寫操作都會立即命中磁碟快閃記憶體,而無需特別小心,這可能會減慢整個過程的速度。(至少你fsync()每次都需要呼叫,並且相信驅動器不會欺騙你。)有了記憶體中的文件,你可以每隔一段時間手動寫回它,或者將它映射到記憶體mmap()並呼叫msync()要求不時將其寫回。

引用自:https://unix.stackexchange.com/questions/685209