我的神经网络库存在问题。它使用多线程来加速计算。但是在运行约30-60秒后,我的程序不再使用100%的i7 3610QM 4cores 8threads了。
基本上我的处理看起来像(c#with pseudocode)
for each training example t in training set
for each layer l in neural network
Parallel.For(0, N, (int i)=>{l.processForward(l.regions[i])})
for each layer l in neural network (but with reversed order)
Parallel.For(0, N, (int i)=>{l.backPropageteError(l.regions[i])})
其中region是图层要处理的神经元预先计算区域的列表。每个区域的大小与当前图层的1 / N相同,因此任务大小相同,以最大限度地减少其他线程需要等待最长任务完成的机会。
就像我说的那样,这种处理方案仅在短时间内消耗100%的处理器然后降低到大约80-85%。在我的例子中,我将N设置为Environment.ProcessorsCount(= 8);
如果有人愿意提供帮助,我可以分享整个代码/存储库。
我试图调查并创建了新的控制台项目,并将几乎Hello World的Parallel.For()放在那里,我根本无法分辨出发生了什么。这可能是Parallel.For()的另一个问题,但我也希望你解决这个问题。这是代码:
class Program
{
static void Main(string[] args)
{
const int n = 1;
while (true)
{
//int counter = 0; for (int ii = 0; ii < 1000; ++ii) counter++;
Parallel.For(0, n, (int i) => { int counter = 0; for (int ii = 0; ii < 1000; ++ii) counter++; });
}
}
}
在这段代码中,我经常(while循环)创建一个有一些工作要做的任务(n = 1)(增加计数器一千次)。据我所知,Parallel.For块执行/等待所有并行调用完成。如果这是真的,它应该与评论部分做同样的工作(提供n = 1)。但是在我的电脑上,这个程序使用100%的CPU,就像有多个线程的工作一样!怎么可能?当我切换到注释版本时,程序使用不到20%的CPU,这是我的预期。请帮我理解这个行为。
答案 0 :(得分:0)
正如@TaW所说,他们是并行的代价。这就是f()
和Parallel.For(0, n, _ => f())
不等同的原因。并行版本引起线程调度和上下文切换。在您的情况下,f()
的执行时间与线程调度开销相当。这就是为什么使用并行版本会降低性能的原因。 Parallel.For
等待操作完成,但是完成得非常快,以至于几个线程在很短的时间内在CPU上运行(请记住,每次调用Parallel.For
时,它都可以选择不同的线程来运行{ {1}}在不同的CPU内核上。
至于问题的第一部分,我猜问题在于传递给f()
的索引范围。而不是[0,CPU核心数量],它应该等于数据的索引范围。