删除互锁。添加并行。For?
我有一些代码来执行一些查找并使用parallel.for 来计算出现次数:
//...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]);
}
}
这个版本比顺序计算快得多。但我想找到一个不同的解决方案来计算发生次数,因为 Interocked.Add 是一个瓶颈。 我正在调查 Plinq 是否是一个选项,但到目前为止还无法找到一种方法来计算数组中 nextPos1 元素的出现次数。
I have some code to do some lookups and count the occurance using parallel.for:
//...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]);
}
}
This version is way faster then a sequential calculation. But i would like to find a different solution to count the occurance as the Interocked.Add is a bottleneck.
I was investigating if Plinq would be an option but wasn't so far able to find a way to count the occurance of the nextPos1 elements in an array.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我基本上建议与汉斯相同的事情,但我认为提供一些代码会很有用。以下是我可能会解决这个问题的方法:
I'd basically suggest the same thing as Hans, but I thought it would be useful to provide some code. Here's how I'd probably tackle the problem:
根据我从代码中得到的信息,如果不锁定 outcounter[i],您将无法正确执行此操作,因为所有线程都将写入 outcounter 中的所有值。
From what I get from the code you aren't going to be able to do this correctly without locking outcounter[i] since all threads are going to write to all the values in outcounter.
有点晚了,但如果您只增加 counter[] 和outerCounter[] 中的值,您可以使用 Parallel.For() 的重载版本
您可以在执行时创建一个本地元素数组,而不是在每个循环中创建一个本地元素数组(并且一次仅由一个线程操作)
例如:
我还没有测试上面的代码,但这就是它的要点。
它将大大减少您调用 Interlocked.Add() 的次数。
有关更多信息,这个网站非常好:
http://www.albahari.com/threading/part5.aspx
Bit late to the party here, but if you're only incrementing the values in counter[] and outerCounter[], you can use an overloaded version of Parallel.For()
Instead of creating a local array of elements each loop, you can create one local to the execution (and will be only operated on by one thread at a time)
For example:
I haven't tested the above code, but that's the jist of it.
It will drastically reduce the amount of times you're calling Interlocked.Add()
For more information, this site is very good:
http://www.albahari.com/threading/part5.aspx