1

私はデルファイで非常に広いファイルを読んでいます

ファイルはカンマ区切りで、ほとんどの時間は文字列の解析に費やされます。

ロジックは次のとおりです

  1. ファイルを開く
  2. 読み込まれた行
  3. 行をレコードの配列に分割する
  4. 吐き出された配列を次のプロシージャに渡します
  5. ステップ 2 に進みます
  6. ファイルを閉じます。

ステップ 3 を並行して実行し、現在 OmniThreadLibrary を調べたいと考えています。

最善のアプローチは何ですか?

Parallel For を使用しますか? ピペレン?またはキュー?

「Parallel For」を使おうと考えているのですが、ファイルが何行あるのかわからないのが問題です

4

3 に答える 3

2

複数のスレッドを使用してファイルを読み取ることから得られるものは何もありません。手順のその部分は、CPU バウンドではなく I/O バウンドです。したがって、単一のスレッドからファイル全体を読み取るのが最善です。

次に、ファイルを行に分割する必要があります。依存関係の問題があるため、これも並行して行うのは難しいことです。行 N+1 は、行 N が終了するところから始まります。単一のスレッドで行に分割するのが最も簡単です。

ただし、I/O とラインへの分割の間でパイプラインを実行できます。ファイルを大きなチャンクで読み取ります (一度に数十 KB など)。そして、各チャンクをパイプラインに渡して、行に処理します。任意の時点でパイプラインに保持できるデータの量に上限を設定する必要がある場合があります。そうしないと、ファイルを処理するよりも速く読み取ることができる場合に、メモリを使い果たす可能性があります。

したがって、このパイプラインには、ファイルを読み取るプロデューサーと、ファイルの内容を行に分割するコンシューマーがあります。

その後、別のパイプラインを実行できます。プロデューサー側には、前のステップで作成された行のリストがあります。これは、各行を処理するコンシューマにパイプラインでプッシュされます。コンシューマーは、parallel for を使用してそれを行います。

于 2014-03-17T13:37:38.597 に答える
0

解析を、たとえば 10.000 行のチャンクに分割することもオプションです。私は OmniThread ライブラリを知らないので、<Do Parallel For on ARR> の部分は自分で行う必要がありますが、コードの基本構造は次のようになります。

CONST ChunkSize = 10000;

VAR ARR : ARRAY[1..ChunkSize] OF STRING;
VAR Lines : Cardinal;
VAR TXT : TextFile;
VAR FileName : STRING;

Lines:=0;
AssignFile(TXT,FileName); RESET(TXT);
WHILE NOT EOF(TXT) DO BEGIN
  IF Lines=ChunkSize THEN BEGIN
    <Do Parallel For on ARR>;
    Lines:=0
  END;
  INC(Lines);
  READLN(ARR[Lines])
END;
<Do Parallel For on ARR - only "Lines" lines>

コードは、<Do Parallel For on ARR> 部分が、配列内のすべてのエントリが処理された後にのみ続行されることを想定していることに注意してください。

于 2014-03-17T15:02:24.337 に答える