0

这可能是一个有点基本的问题(我不得不承认,我对并行编程不是很有经验)。

我编写了一个单线程 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;

  }
}

由于评估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 ] );
    } );
  }

我天真的期望是,对于每个段(即 each idx),内部的处理将被一致地处理,特别是在创建 eachnew Agent( p, cost_function( p ) )时,该表达式中的两个p将是相同的,并且结果Agent确实包含一个对应的参数和函数值对。但我得到的是new Agent( p1, cost_function( p2 ) ),而且我什至认为不一定p2是原始parameter数组的一部分。

如果我将最后一条语句锁定在该例程中,则该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 回答