これはやや基本的な質問かもしれません (私は並列プログラミングの経験があまりないことを認めなければなりません)。
パラメーターの配列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
ことを考えました。かなり素朴に、私はルーチンを次のように変更しました。parameter
Parallel.For
optimise
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 ) )
思いません。p2
parameter
最後のParallel.For
ステートメントをロックすると、ルーチンは正常に機能しますが、もちろん、それでは並列化が役に立たなくなります。cost_function
元のルーチンを変更する必要のない一貫したパラメーター/値のペアで結果マトリックスが満たされるようにするためのより良い方法はありますか?
もしそうなら、これを説明する優れたオンライン リソースはありますか? そして最後の質問です。このトピックに関する良い本は何ですか?
前もって感謝します!ベスト、ロブ