【问题标题】:Using all cores in pc with c#使用 c# 使用 pc 中的所有内核
【发布时间】:2012-01-11 14:35:08
【问题描述】:

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

我正在尝试通过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);

【问题讨论】:

  • 我会假设某种优化可能会删除你的循环,因为它没有做任何事情。这不是 DateTime.Now 的正确使用。只是有很多错误。
  • 我试图添加一些工作,现在它需要相同的大部头......所以你没事(ofcurse)。它只需要一些东西来工作:)
  • 乔是对的;使用秒表进行性能分析。 DateTime.Now 没有足够好的精度。
  • 你不应该做的问题与你的性能问题没有直接关系。 inputData = inputData++; 不应该这样做,因为 ++ 已经更新了淡水河谷。此外(也是更重要的问题),由于所有线程在没有任何同步的情况下读取和写入同一个变量,您可能会弄乱变量的值。

标签: c# .net multicore


【解决方案1】:

那么,更快的方法是:自己不工作,还是雇佣十个人每人只做十分之一的不工作?

您做错的是您的示例完全是人为的。 jitter 完全意识到,一遍又一遍地将零分配给未使用的同一个本地是没有意义的,因此它可能正在消除工作。即使不是,这项工作也是微不足道的。设置所有线程的工作比自己做的工作要大。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      在堆栈上设置 现有 值类型的值非常简单。与此相比,创建和跟踪线程的成本会很大。 为您的操作添加任何复杂性都会极大地改变您的结果。即使创建和设置一个等于添加两个字符串的字符串变量也会大大增加完成的工作。尝试一些更复杂的东西(几乎任何事情都可以!),你会发现并行库的价值增加了​​。

      试试这个:

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

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

      • 数据访问
      • 磁盘 IO
      • 复杂的数学
      • 列表的过滤/排序/投影等

      ,结果将有利于并行性。

      【讨论】:

      • 接触字符串会给 GC 带来压力。如果这里的 GC 比实际代码更昂贵,我不会感到惊讶。
      • @CodeInChoas,为迂腐道歉,你的意思是连接吗?
      【解决方案4】:

      多线程有开销。对于与设置线程所需的时间相比需要较长时间的操作,很棒。

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

      【讨论】:

        【解决方案5】:

        代码的并行化涉及相当大的开销,并且您正在使用它来执行琐碎的操作。这就是为什么您的代码运行非常缓慢的原因。只有在充实代码后,您才会看到改进,并且您的代码会执行大量 CPU 密集型操作。

        【讨论】:

          【解决方案6】:

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

          您确实需要考虑需要处理多少数据、并发级别以及需要共享多少易失数据(需要多少锁定)。

          【讨论】:

            【解决方案7】:

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

            【讨论】:

            • 一个有效的更正,但他应该使用StopWatch
            • 在这种情况下,他仍然必须使用 TotalSeconds 或 TotalMilliseconds
            【解决方案8】:

            我怀疑,在没有我自己的经验证据的情况下,排队额外线程的开销超过了好处。您所要求的是要同时执行 20 亿件工作,这在没有检查的情况下我怀疑使用 ThreadPool 的并行队列。

            【讨论】:

              猜你喜欢
              • 2019-01-22
              • 2016-05-31
              • 1970-01-01
              • 2017-12-06
              • 2018-12-15
              • 2019-01-05
              • 2011-03-26
              • 1970-01-01
              相关资源
              最近更新 更多