我编写了一些代码来使用Parallel.For和线程局部变量。它基本上是一个大数组的总和,但是数组的元素在它们被求和的同时在for循环中显式计算。
我遇到的问题是我的线程局部变量是非常非常重的对象。他们占用200 MB的内存并不罕见。我注意到我的程序的内存使用量将达到2 gb,然后GC会将其降低到200 mb并且上下移动,这表明正在分配许多临时值。因为我需要几个线程局部变量,所以我将它们包装在一个struct对象中。这允许我在构造函数中添加一个Console.WriteLine,我看到很多我的对象被创建,而我只想在我的机器上每个核心有一个构造。我怎样才能强制它创建精确的(numberOfCores)线程并且只保留那些直到最后?
我添加了
ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = 2;
只有轻微的帮助。我仍然得到太多的结构构造。看起来我可以用options.TaskScheduler做些什么,但我似乎无法理解它的强大程度。看起来我可以自己滚动,这几乎是可怕的。如果可能,我不想这样做。
以下是我程序中相关的代码部分。
ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = 2;
Parallel.For<ThreadLocalData>(0, m, options,
// Thread local variable initialization
() => new ThreadLocalData(new DenseMatrix(r * r, r * r, 0),
new DenseMatrix(r * r, r * r, 0),
new DenseMatrix(r, r, 0)),
// Per-thread routine
(row, loop, threadLocalData) =>
{
threadLocalData.kronProductRight.Clear();
for (int column = 0; column < n; ++column)
{
if ((int)E[row, column] == 1)
threadLocalData.kronProductRight.Add(Yblocks[column], threadLocalData.kronProductRight);
}
MathNetAdditions.KroneckerProduct(Xblocks[row], threadLocalData.kronProductRight, threadLocalData.kronProduct);
threadLocalData.subtotal.Add(threadLocalData.kronProduct, threadLocalData.subtotal);
return threadLocalData;
},
(threadLocalData) =>
{
lock (mutex)
A.Add(threadLocalData.subtotal, A);
}
);
答案 0 :(得分:1)
查看这篇文章http://blogs.msdn.com/b/pfxteam/archive/2010/10/21/10079121.aspx特别是有关Parallel.For的部分,当初始化委托很昂贵时会出现性能问题。
从查看上面的代码很难说,但看起来你应该能够将ThreadLocalData的计算/数据部分与它的有状态/变异部分分开?理想情况下,您可以将对ThreadLocalData的不可变版本的引用传递给任何正在处理您的数字的内容。这样,无论如何,你只是处理一个实例。
答案 1 :(得分:0)
我没有深入了解你的问题(似乎你正在问phoog指出的错误问题),但要回答你的具体问题:
如何强制它创建精确(numberOfCores)线程并保持 只有那些直到最后?
你有一个完成这个的调度程序: