在并行中删除互锁的add。
-
26-10-2019 - |
题
我有一些代码可以进行一些查找,并使用并行来计算这种情况。
//...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
不隶属于 StackOverflow