C#串行用于-->;parallel For:结果混乱

本文关键字:For parallel 结果 混乱 gt 用于 | 更新日期: 2023-09-27 18:29:14

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

我编写了一个单线程C#程序,在此过程中创建了一个参数数组p,然后用函数f对每个参数p[i]进行求值,然后将每个求值的对( 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),的内部将得到一致的处理,特别是在创建每个new Agent( p, cost_function( p ) )时,该表达式中的两个p将是相同的,并且得到的Agent确实包含一对相应的参数和函数值。但我得到的是new Agent( p1, cost_function( p2 ) ),我甚至不认为p2必然是原始parameter数组的一部分。

如果我锁定了Parallel.For例程中的最后一条语句,它可以正常工作,但这当然会使并行化变得毫无用处。有没有更好的方法可以确保结果矩阵中充满一致的参数/值对,而不需要更改原始的cost_function例程?

如果是的话,有没有一个好的在线资源可以解释这一点?最后一个问题是:什么是一本关于这个主题的好书?

提前感谢!最佳,Rob

C#串行用于-->;parallel For:结果混乱

没有完整的代码很难掌握它,但我认为你的意思是:

var result = from parameter in parameters.AsParallel()
             select new Agent(parameter, cost_function( parameter));