0

これはやや基本的な質問かもしれません (私は並列プログラミングの経験があまりないことを認めなければなりません)。

パラメーターの配列pが作成される単一のスレッド化された C# プログラムを作成しました。次に、各パラメーターp[i] が functionfで評価され、各評価のペア( p[i], f( p[i] ) )が Heap に配置されます (関数値で並べ替えられます)。非常に大まかに、次のようになります。

class Agent {
  private double[] parameter;
  private double value;

  public Agent( double[] par, double val ) { this.parameter = par; this.val = value; }
}

class Work {

  public void optimise() {

    // return an array of parameters, each one of which is a double array itself
    double[][] parameter = getParameters();
    Agent[] results = new Agent[ parameter.Length ];

    for ( int idx = 0; idx < parameter.Length; idx++ )
      results[ idx ] = new Agent( parameter[idx], cost_function( parameter[ idx ] ) );

  }

  private double cost_function( double[] par ) {

    // evaluate par, get result
    return result;

  }
}

の評価cost_functionはかなり長くて長いので、それを並列化し、 の内容をセグメントに分割してから、各セグメントで使用するparameterことを考えました。かなり素朴に、私はルーチンを次のように変更しました。parameterParallel.Foroptimise

  public void optimise() {

    // select an appropriate number of threads, e.g.
    int number_of_threads = Environment.ProcessorCount;

    // return an array of parameters, each one of which is a double array itself
    double[][] parameter = getParameters();

    // split the array of parameters into #number_of_threads many 
    // segments (of roughly equal size)
    double[][][] par_segments = distribute_parameter( parameter );

    Agent[][] results = new Agent[ number_of_threads ];


    // process each segment in an individual thread
    Parallel.For( 0, number_of_threads, idx => {

      results[ idx ] = new Agent[ par_segments[ idx ].Length ];
      for ( int agent = 0; agent < par_segments[ idx ].Length; agent++ )
        results[ idx ][ agent ] = 
          new Agent( par_segments[ idx ][ agent ], cost_function( par_segments[ idx ][ agent ] );
    } );
  }

私の素朴な期待は、各セグメント (つまり、各idx) について、 の内部が一貫して処理されること、特に、 each の作成時に、その式new Agent( p, cost_function( p ) )の 2 つpが同一であり、結果としてAgent実際に が含まれることでした。パラメータと関数値の対応するペア。しかし、代わりに得られるのは であり、元の配列の一部である必要があるとはnew Agent( p1, cost_function( p2 ) )思いません。p2parameter

最後のParallel.Forステートメントをロックすると、ルーチンは正常に機能しますが、もちろん、それでは並列化が役に立たなくなります。cost_function元のルーチンを変更する必要のない一貫したパラメーター/値のペアで結果マトリックスが満たされるようにするためのより良い方法はありますか?

もしそうなら、これを説明する優れたオンライン リソースはありますか? そして最後の質問です。このトピックに関する良い本は何ですか?

前もって感謝します!ベスト、ロブ

4

1 に答える 1

0

完全なコードがないと難しいですが、次のような意味だと思います。

var result = from parameter in parameters.AsParallel()
             select new Agent(parameter, cost_function( parameter));
于 2013-08-28T10:04:43.007 に答える