这可能是一个基本的问题(我必须承认,我对并行编程不是很有经验)。
我编写了一个单线程C#程序,在此期间创建了一个参数数组p
,然后使用函数p[i]
评估每个参数f
,并( p[i], f( p[i] ) )
对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;
}
}
然后将每个评估的1}放入Heap(按功能值排序)。非常粗略,它看起来像这样:
cost_function
由于parameter
的评估相当冗长,而且parameter
很长,所以我考虑将其并行化,将Parallel.For
的内容分成段,然后使用{{1}在每个细分上。相当天真,我将例程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
),内部将被一致地处理,特别是在每个new Agent( p, cost_function( p ) )
的创建中,两个{{ 1}}在那个表达式中是相同的,并且结果p
确实包含一对相应的参数和函数值。但我得到的是Agent
,我甚至不认为new Agent( p1, cost_function( p2 ) )
是原始p2
数组的一部分。
如果我锁定其中的最后一个语句,parameter
例程工作正常,但当然这会使并行化无用。
有没有更好的方法来确保结果矩阵将填充一致的参数/值对,而不需要更改原始的Parallel.For
例程?
如果是这样,是否有一个很好的在线资源可以解释这一点?最后一个问题:关于这个主题的什么是好书?
提前致谢! 最好的,罗布
答案 0 :(得分:0)
没有完整的代码就很难掌握它,但我认为你的意思是这样的:
var result = from parameter in parameters.AsParallel()
select new Agent(parameter, cost_function( parameter));