2010-02-28 64 views
2

我希望我的代碼能夠非常快速地處理文件。此文件大小將從單個KB到甚至2 GB不等。需要快速文件訪問選項

即使我準備爲該單個文件創建單獨的文件系統。

我會將文件分割爲常量大小的塊(可能爲8KB)並訪問它以進行數據讀取和寫入。代碼明智的是,該算法不能改變,因爲它提供了良好的性能和穩定的性能。所以我不想改變。我也使用mmap()將塊按需映射到內存。

是否有可能將文件系統作爲單個塊來讀取文件,讀寫操作可以更快?

請給出你的所有建議,即使是一個小東西,這將幫助我。

建議可以跨平臺和文件系統。

感謝, 娜迦

+1

你打算使用什麼操作系統?什麼語言? – 2010-02-28 07:10:46

+0

我的代碼應該可以跨OS使用。爲了簡單起見,我想在Linux(Fedora 11)中實現您的建議,我使用的是C語言。 – Naga 2010-02-28 07:45:05

回答

0

mmapMapViewOfFile讓你直接訪問內存中的文件。操作系統將根據需要透明地在頁面中出錯,或者甚至可能提前讀取(可以用madviseFILE_FLAG_*來暗示)。根據您的訪問模式和文件大小,這可能比讀取/寫入文件通常快得多。

不利的一面是,您將不得不擔心一致性問題(請務必謹慎使用msyncFlushViewOfFile),並且由於必需的可分頁操作,它可能也會變得更慢。

+0

我明白mmap()將會是更好的選擇,因此我正在使用它。現在我將文件分割爲8k塊。是否有任何硬塊和快速的塊大小規則?示例:如果我訪問某個特定的塊,則會加載單頁錯誤。 – Naga 2010-02-28 08:26:43

+0

目前大多數常見平臺上的塊大小爲4kB或8kB,儘管http://linux-mm.org/HugePages Linux可以讓你'mmap(... MAP_HUGETLB ...)'這可能會給你2MB或4MB的頁面;有了這個,頁面錯誤就會減少,但每個頁面都會花費更長時間才能滿足。並且不要認爲操作系統只按需要映射頁面,然後將它們留在它們周圍:它可能會提前讀取並搶先映射更多頁面,或者它可能會丟棄它需要/想要驅逐的頁面。在你自己的系統上做自己的實驗,結果*會根據許多因素而變化。 – ephemient 2010-02-28 08:53:29

0

Windows允許您打開原始讀取和寫入的分區。它也可以讓你打開一個原始IO的物理設備。因此,如果您願意將硬盤或分區視爲單個文件,則可以保證「文件」在磁盤上在邏輯上連續。 (由於硬盤對壞扇區執行修補程序的方式,實際上可能不是物理上連續)。

如果您選擇做原始io,那麼您將不得不讀取和寫入設備塊大小的倍數。這通常是512字節,但將4k用作塊大小可能會更明智一些,因爲這是更新的磁盤正在使用的內容,也就是Win32的頁面大小。

要打開原始讀取的分區,請使用文件名爲「\。\ X:」的CreateFile,其中X:是分區的驅動器號。參見下節標題物理磁盤和卷

在另一方面的CreateFile文檔,這是相當難打的內存性能映射文件,看到這個問題的一個例子 How to scan through really huge files on disk?

+0

我明白mmap()將會是更好的選擇,因此我正在使用它。現在我將文件分割爲8k塊。是否有任何硬塊和快速的塊大小規則?示例:如果我訪問某個特定的塊,則會加載單頁錯誤。 – Naga 2010-02-28 08:27:03

0

總是試圖以64kB-1MB爲單位順序訪問您的文件。這樣,您就可以利用預取並最大化每個I/O操作的數據量。

此外,請嘗試確保文件首先是連續的,以便磁盤頭不必在連續讀取之間移動很多。如果您通過設置文件末尾或一次執行整個文件的步驟開始,許多文件系統將創建儘可能連續的文件。在Windows上,您可以使用sysinternals.com實用程序contig.exe使文件連續。

1

通用,獨立於操作系統的一般規則:

  • 使用物理讀取(而不是 流)

  • 使用您的讀取大I/O緩衝區。 I/O操作的初始化(以及與旋轉硬件的同步)是花費時間的。幾個小的閱讀需要比一個大的閱讀長。

  • 創建一些基準來找出最有效的緩衝區大小。在給定尺寸之後,效率不會提高,而且您不希望無用地吞噬所有珍貴的RAM。最佳緩衝區大小取決於您的硬件和操作系統。在當前的硬件上,使用500KB到1MB範圍內的緩衝區大小通常足夠有效。

  • 最小化磁頭尋找。即如果必須將數據寫回,則讀/寫交替可能會非常昂貴(如果它們屬於同一物理磁盤)。

  • 如果你有一些重要的處理要做,使用雙緩衝和異步IO重疊IO和處理。