使用c#中的所有内核使用

时间:2012-01-11 14:35:09

标签: c# .net multicore

*请注意,我只是在测试以了解这一点。

我正在尝试使用Parallel.For()方法使用计算机的所有核心。这工作正常,但是当我尝试使用普通for循环的相同方法时,它会更快。并行方法需要16秒,而正常方法只需要6秒。

我希望你能告诉我这里做错了什么。

更新了代码

        DateTime parallelStart = new DateTime();
        DateTime parallelFinish = new DateTime();
        DateTime singeStart = new DateTime();
        DateTime singeFinish = new DateTime();
        parallelStart = DateTime.Now;
        int inputData = 0;

        Parallel.For(0, 1000000000, i =>
        {
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
        });

        parallelFinish = DateTime.Now;
        singeStart = DateTime.Now;

        for (int i = 0; i < 1000000000; i++)
        {
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
        }

        singeFinish = DateTime.Now;
        MessageBox.Show("Parallel execution time: " + (parallelFinish - parallelStart).Seconds + "\n" +
                        "Singe execution time: " + (singeFinish - singeStart).Seconds);

第一个代码:

DateTime parallelStart = new DateTime();
DateTime parallelFinish = new DateTime();
DateTime singeStart = new DateTime();
DateTime singeFinish = new DateTime();
parallelStart = DateTime.Now;

Parallel.For(0, 2000000000, i =>
{
    var inputData = 0;
});

parallelFinish = DateTime.Now;
singeStart = DateTime.Now;

for (int i = 0; i < 2000000000; i++)
{
    var inputData = 0;
}

singeFinish = DateTime.Now;
MessageBox.Show("Parallel execution time: " + (parallelFinish - parallelStart).Seconds + "\n" + "Singe execution time: " + (singeFinish - singeStart).Seconds);

8 个答案:

答案 0 :(得分:14)

嗯,什么更快:自己不做工作,或雇用十个人,每个人做十分之一没有工作?

你做错了是你的例子完全是人为的。抖动完全意识到将零重复分配给一次又一次未使用的同一本地是没有意义的,因此它可能会消除工作。即使不是,这项工作也是微不足道的。设置所有线程的工作比仅仅自己完成工作要大。

做一个真正的测试 - 做一些光线追踪或在那里产生分形或其他东西。 做一些现实的事情,在一个线程上花费几分钟或几个小时。你不能合理地期望在工作上节省太多容易。

答案 1 :(得分:10)

这可能是因为创建线程的开销和它们之间的争用比操作本身花费的时间更多。尝试在循环中放入更复杂的东西,我敢打赌你的结果会改变。

答案 2 :(得分:3)

在堆栈上设置现有值类型的值是令人难以置信的,非常微不足道的。与此相比,创建和跟踪线程的成本会很高。 为您的操作添加任何复杂性会大幅改变您的结果。即使创建和设置一个等于两个字符串附加的字符串变量,也会大大增加完成的工作量。尝试更复杂的东西(几乎任何事情都可以!),你会看到并行库的价值增加。

试试这个:

Parallel.For(0, 2000000000, i =>
{
    var string inputData = "ninjas " + "like " + "taco";
});

信不信由你,我们在这里添加了很多更多处理。 (在后台创建并抛出多个字符串)这将改变您的结果。然后当你认为我们在这些循环中做了更复杂的事情时,比如:

  • 数据访问
  • disk IO
  • 复杂的数学
  • 过滤/排序/预测列表等

,结果将是戏剧性的,有利于并行性。

答案 3 :(得分:2)

多线程有开销。对于花费很长时间而不是设置线程所花费的时间的操作,很棒。

但是在你的情况下,你有一个非常简单的循环体,创建线程来完成工作的开销超过了并行执行它的好处。

答案 4 :(得分:2)

代码的并行化涉及相当大的开销,并且您正在使用它来执行简单的操作。这就是你的代码运行速度非常慢的原因。只有在使用代码时才会看到改进,并且代码会执行大量CPU密集型操作。

答案 5 :(得分:1)

正如大多数关于并行编程的书都会提到的那样,“总是衡量性能”。不要假设并行比使用直接循环更快,因为并行性包括开销。

您确实需要考虑需要处理多少数据,并发级别以及需要发生多少挥发性数据共享(需要多少锁定)。

答案 6 :(得分:0)

在测量时间时使用TotalSeconds而不是秒。

答案 7 :(得分:0)

我怀疑,在没有我自己的经验证据的情况下,排队额外线程的开销超过了收益。你要求的是要同时执行的2bn个工作,没有检查我怀疑与ThreadPool并行队列。