2013-09-28 123 views
0

可以說我有在這樣的格式N個文件的組合:多線程文件(共享存儲器)

一個文件看起來像這樣:
對於每個時間有不同的ID

數據的一定量的
- time 1: 
     - data with id: 10 
     - data with id: 13 
     - data with id: 4 
- time 2: 
     - data with id: 10 
     - data with id: 77 
...etc 

(每次從1-1000與IDS的數據被鋪展一些如何(混合)在這些N個文件)

竟被我ð喜歡讓我有被下令單個文件到所有這些N個文件結合:

最終文件:

- time 1: 
     - data with id: 1 
     - data with id: 2 
     - data with id: 3 
     - ... 
     - data with id: 1000 

- time 2: 
     - data with id: 1 
     - data with id: 2 
     - data with id: 3 
     - ... 
     - data with id: 1000 
...etc 

數據ID 1-1000的大小約爲100MB,但我有很多時候它佔據了高達50GB的數據。

我對這個問題的解決辦法是,到目前爲止這樣使這一儘可能快:

我用一臺超級計算機節點上牛逼線程(1臺電腦,例如24-48核)(例如)。 我已分配了一個共享存儲器數組來保存與IDS 1所有DATAS - 1000一次性(也可以是更多的,如果我喜歡)

步驟:
第1步:

  • 每個線程都有一些打開並擁有的文件。然後每個線程將其在文件中具有的ID的數據填入 到共享數組中。

步驟2:

  • 當所有線程都處理最後一個時間 - >線程1有序形式寫入 此數組到最終文件。

asdasd

  1. 我會非常感興趣,如果這是有效的?無論如何, 並行讀取是否無序,因此完全沒有用處? 我可以計算本地計算機與超快SSD或與網絡存儲 (Lustres或Panasas的文件系統)
  2. 我能再次使用的所有線程在 步驟2在平行於寫入到磁盤的集羣節點上的最終文件可以說MPI IO(其中 支持偏移量並行寫入),或者如何可以實現 ? - > C++標準庫?

感謝您的任何意見!

回答

1

對於適量的數據,您的方法可能會工作正常,但您已將一個等級作爲通信的中心點。這不會很好地擴展。

您的第2部分正處於正確的軌道:使用MPI-IO進行並行寫入聽起來像是一種很好的方法。以下是可能的結果:

  1. 繼續讓您的T進程讀取它們的輸入。
  2. 我假設'id'密度很大。我的意思是,在這個文件集合中,一個進程可以知道它是否看到data with id: 4其他一些進程擁有id 1,2,3和5?如果是這樣,那麼每個進程都知道數據的去向。
  3. 我們還假設每個'數據'是固定的大小。如果情況並非如此,這種方法只會更復雜一點。

如果您不知道最大ID和最大時間步數,那麼您需要進行一些通信(MPI_Allreduce和MPI_MAX作爲操作)才能找到它。

有了這些預賽中,你可以設置一個MPI-IO「文件視圖」,可能使用MPI_Type_indexed

秩0,這變得有點複雜,因爲你需要添加到您的數據的時間步標記列表。或者,您可以定義具有時間步長索引的文件格式,並將該索引存儲在頁眉或頁腳中。

的代碼看起來大致是這樣的:

for(i=0; i<nitems; i++) 
    datalen[i] = sizeof(item); 
    offsets[i] = sizeof(item)*index_of_item; 
} 
MPI_Type_create_indexed(nitems, datalen, offsets, MPI_BYTE, &filetype); 
MPI_File_set_view(fh, 0, MPI_BYTE, filetype, "native", MPI_INFO_NULL); 
MPI_File_write_all(fh, buffer, nitems*sizeof(item), MPI_BYTE, &status); 

的_all此位是很重要的:你要創建從每個MPI處理器高度不連續的,不規則的訪問模式。爲MPI-IO庫提供一個優化該請求的機會。

此外,重要的是要注意MPI-IO文件視圖必須是單調不減少的,所以在集體寫出數據之前,您必須對本地項進行排序。本地內存操作相對於I/O操作而言成本很低,所以這通常不是什麼大問題。