0

次のような形式の N 個のファイルがあるとします。

1 つのファイルは次のよう
になります。 異なる 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 までの ID を持つデータが、これらの 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 のサイズは約 100 MB ですが、最大 50 GB のデータを占めることが多くあります。

この問題に対する私の解決策は、これを可能な限り高速にするために、これまでのところ次のようになります。

スーパーコンピューター ノード (たとえば、24 ~ 48 コアのコンピューター 1 台) でT スレッドを使用します (たとえば)。ID 1 ~ 1000 のすべてのデータを一度に保持するために、共有メモリ配列を割り当てました(必要に応じてそれ以上にすることもできます)。

手順:
ステップ 1:

  • 各スレッドには、開いて所有するいくつかのファイルがあります。次に、各スレッドは、ファイル内にある ID のデータを共有配列に入力します。

ステップ2:

  • すべてのスレッドが最終的に 1 回処理されると、スレッド 1 はこの配列を順序付けられた形式で最終ファイルに書き込みます。

アスダス

  1. それが効率的であれば、私は非常に興味がありますか?とにかく並列読み取りは順次化されていないので、まったく役に立ちませんか? 超高速 SSD を備えたローカル コンピューター、またはネットワーク ストレージ (Lustres または Panasas ファイルシステム) を備えたクラスター ノードで、最終的なファイルを計算できました。
  2. ステップ 2 ですべてのスレッドを再び使用してディスクに並列に書き込むことはできますか (オフセットによる並列書き込みをサポートする MPI IO を使用します)、または他にどのように達成できますか? -> C++ 標準ライブラリ?

ご意見ありがとうございます。

4

1 に答える 1

1

あなたのアプローチは、適度な量のデータに対してはおそらく問題なく機能しますが、ここではコミュニケーションの中心点を 1 つにしました。それはひどくうまくスケーリングするつもりはありません。

あなたはパート 2 で正しい軌道に乗っています。MPI-IO を使用した並列書き込みは、私にとって良いアプローチのように思えます。それがどのように進むかは次のとおりです。

  1. 引き続き T プロセスに入力を読み取らせます。
  2. 「id」が密に割り当てられていると仮定します。つまり、このファイルのコレクションでは、data with id: 4他のプロセスの ID が 1、2、3、および 5 であることをプロセスが認識できるということです。もしそうなら、すべてのプロセスはデータがどこに行かなければならないかを知っています。
  3. また、各「データ」が固定サイズであると仮定しましょう。そうでない場合、アプローチはもう少し複雑になります。

最大IDと最大タイムステップがわからない場合は、それを見つけるために少し通信する必要があります(操作としてMPI_MAXを使用したMPI_Allreduce)。

これらの準備が整ったら、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 操作に比べてわずかであるため、通常は大したことではありません。

于 2013-11-05T15:58:31.660 に答える