多线程填充数组

Multithreading Fill Array

在 C# Net 2.0 上

代码运行速度比单线程版本稍慢。 xDiff = 2100, yDiff = 2000;单线程中将近 14 秒,多线程中为 16 秒(此代码)。一定是出了什么问题。 我需要填写结果数组。数组节点只写一次数据,没有读,所以应该适合多线程。

double[,] result = new double[xDiff, yDiff];
int threadCount = Environment.ProcessorCount;
ManualResetEvent finished = new ManualResetEvent(false);
int perthread = xDiff / threadCount;
int left = xDiff % threadCount;
int toProcess = threadCount;
int s = 0;
int e = left;
for (int ii = 0; ii < threadCount; ii++)
{
  ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state)
    {
      for (int x = s; x < e; x++)
        for (int y = 0; y < yDiff; y++)
        {
          result[x, y] = DoWork((xStart + x), (yStart + y), p)
        }
      if (System.Threading.Interlocked.Decrement(ref toProcess) == 0) finished.Set();
    }), null);
  s = e;
  e += perthread;
}
finished.WaitOne();
return result;

xStart,yStart 是double,p 是大的class。 DoWork 函数只调用 p 的一些函数而不调用 writes/change class.

上的任何数据

简要结果[x, y] = DoWork((xStart + x), (yStart + y), p); 我需要尽快填充数组。我该怎么做?

我认为这里的问题是变量 se 是在线程外被修改的闭包,所以线程得到了错误的值并且使用了不正确的范围。

要查看是否是这种情况,请尝试添加一个 Console.WriteLine()Trace.WriteLine() 以在线程内打印出 se 的值(在打电话给 QueueUserWorkItem()) 看看这是不是正在发生的事情。

要解决此问题,请将修改后的闭包复制到临时变量中并在线程中使用它们,如下所示:

for (int ii = 0; ii < threadCount; ii++)
{
    int ts = s; // Copy them outside the loop.
    int te = e;
    ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state)
    {
        for (int x = ts; x < te; x++) // Use the copy here.

另见 Access to Modified Closure