1

たとえば、次のコードを見てください。

for i := (myStringList.Count - 1) DownTo 0 do begin
  dataList := SplitString(myStringList[i], #9);
  x := StrToFloat(dataList[0]);
  y := StrToFloat(dataList[1]);
  z := StrToFloat(dataList[2]);
  //Do something with these variables
  myOutputRecordArray[i] := {SomeFunctionOf}(x,y,z)
  //Free Used List Item 
  myStringList.Delete(i);
end;
//Free Memory
myStringList.Free;

たとえば、OmniThreadLibrary を使用してこれをどのように並列化しますか? 出来ますか?それとも再構築する必要がありますか?

は大きく、各反復で使用した後にアイテムを解放することは、メモリ使用量を最小限に抑えるために重要であるため、myStringList.Delete(i);各反復で呼び出しています。StringList

4

3 に答える 3

2

簡単な答え: そうしないでしょう。

より複雑な回答: 並列化された操作で最後に行うことは、この削除呼び出しなどの共有状態の変更です。個々のタスクが「順番どおりに」完了することは保証されていないため、実際には、少なくとも 1 回は完了しない可能性が高く、その確率は合計ワークロードにタスクを追加するほど急速に 100% に近づきます。そのようなことをしようとするのは火遊びです。

アイテムを破棄してシリアル化するか、並行して実行してより速く終了し、リスト全体を破棄することができます。しかし、私はそれを両方の方法で持つ方法はないと思います。

于 2014-11-25T22:35:00.747 に答える
2

あなたはだますことができます。文字列値を空の文字列に設定すると、ほとんどのメモリが解放され、スレッド セーフになります。処理の最後に、リストをクリアできます。

Parallel.ForEach(0, myStringList.Count - 1).Execute(
  procedure (const index: integer)
  var
    dataList: TStringDynArray;
    x, y, z: Single;
  begin
    dataList := SplitString(myStringList[index], #9);
    x := StrToFloat(dataList[0]);
    y := StrToFloat(dataList[1]);
    z := StrToFloat(dataList[2]);
    //Do something with these variables
    myOutputRecordArray[index] := {SomeFunctionOf}(x,y,z);
    //Free Used List Item
    myStringList[index] := '';
  end);
myStringList.Clear;

複数のスレッドから共有オブジェクトに書き込むことはないため、このコードは安全です。通常はローカルで使用するすべての変数が、スレッド化されたブロックで宣言されていることを確認する必要があります。

于 2014-11-25T23:28:23.927 に答える
1

パフォーマンスの向上につながらない悪い考えであるため、最初に尋ねたことを実行する方法を示すつもりはありません。提案された並列実装で多くのさまざまなデータ競合に対処することを想定していません。

ここでのボトルネックはディスク I/O です。ファイル全体をメモリに読み込んで内容処理することは、メモリの問題を引き起こす設計上の選択です。この問題を解決する正しい方法は、パイプラインを使用することです。

パイプラインのステップ 1 は、ディスク上のファイルを入力として受け取ります。このコードは、ファイルのチャンクを読み取り、それらのチャンクを行に分割します。これらの行は、このステップの出力です。ファイル全体が一度にメモリに存在することはありません。読み取るチャンクのサイズを調整する必要があります。

ステップ 2 は、ステップ 1 で生成された文字列を入力として受け取ります。ステップ 2 では、これらの文字列を使用してベクトルを生成します。これらのベクターは、ベクター リストに追加されます。

I/0 は非常に高価なため、ステップ 2 はステップ 1 よりも高速です。したがって、並列アルゴリズムを使用していずれかのステップを最適化しようとしても、何も得られません。ユニプロセッサ マシンでも、このパイプライン化された実装は、パイプライン化されていないものよりも高速になる可能性があります。

于 2014-11-26T07:24:52.027 に答える