我有一些代码可以进行一些查找,并使用并行来计算这种情况。

//...initialize _table with int values...
int elements=60;
int[] outerCounter=new int[elements];
Parallel.For(1, 2000, i0=>
{
  int[] counter=new int[elements];
  int nextPos0=_table[10+i0];
  for(i1=i0+1; i1<1990; i1++){ 
    //...here are also some additionale calculations done...  

    int nextPos1=_table[nextPos0+i1];
    counter[nextPos1]++;
  }
  //synchronize
  for(int i=0; i<elements;i++){
    Interlocked.Add(ref outerCounter[i], counter[i]);
  }
}

此版本的速度比顺序计算快。但是我想找到一个不同的解决方案来计算发生的情况,因为ADD是瓶颈。我正在调查是否可以选择Plinq,但是到目前为止无法找到一种方法来计算阵列中NextPOS1元素的发生。

有帮助吗?

解决方案

我基本上建议与汉斯同样的事情,但我认为提供一些代码将很有用。这是我可能解决这个问题的方法:

//...initialize _table with int values...
int elements=60;
List<int[]> outerCounter=new List<int[]>();
Parallel.For(1, 2000, i0=>
{
  int[] counter;
  lock(outerCounter)
  {
    if (outerCounter.Count == 0)
      counter = new int[elements];
    else
    {
      counter = outerCounter[outerCounter.Count - 1];
      outerCounter.RemoveAt(outerCounter.Count - 1);
    }
  }
  int nextPos0=_table[10+i0];
  for(i1=i0+1; i1<1990; i1++){ 
    //...here are also some additionale calculations done...  

    int nextPos1=_table[nextPos0+i1];
    counter[nextPos1]++;
  }
  lock (outerCounter)
    outerCounter.Add(counter);
});

int totalCounter = new int[elements];
Parallel.For(0, elements - 1, i =>
{
  foreach (int[] counter in outerCounter)
    totalCounter[i] += counter[i];
});

其他提示

从我从代码中获得的内容,您将无法正确执行此操作,而无需锁定郊外[i],因为所有线程都将在郊外的所有值中写入所有值。

在这里稍晚稍晚,但是如果您仅在计数器[]和outerCounter []中递增值,则可以使用Parallel.for()的超载版本
您可以为执行的局部创建一个本地元素(并且一次仅由一个线程操作),例如:

int elements=60;
int[] outerCounter=new int[elements];

Parallel.For (1, 2000,
  () => new int[elements],                        // Initialize the local value.    
  (i0, state, counter) =>
    {
        int nextPos0=_table[10+i0];
        for(i1=i0+1; i1<1990; i1++)
        { 
            //...here are also some additionale calculations done...  
            int nextPos1=_table[nextPos0+i1];
            counter[nextPos1]++;
        }
    }

  counter =>                                    // Add the local value
    { 
        for(int i=0; i<elements;i++)
        {
            Interlocked.Add(ref outerCounter[i], counter[i]);
        }
    }
);

我尚未测试上述代码,但这就是其中的JIST。它将大大减少您调用互锁的次数。ADD()

有关更多信息,此网站非常好:http://www.albahari.com/threading/part5.aspx

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top