【问题标题】:.Net 4.0 code will run on Core 2 Duo but not i5. Advice needed.Net 4.0 代码将在 Core 2 Duo 上运行,但不在 i5 上。需要建议
【发布时间】:2012-01-14 16:46:35
【问题描述】:

我编写了一些非常复杂的多线程代码。它使用旋转、产量和联锁库。

代码在我的 Core 2 Duo 2 GHz 机器上完美运行。在我的 i5 2.4 GHz 双核四线程机器上,它很慢(就像比 Core 2 慢),或者完全无法运行(只是处于 0% CPU)。

两台机器都有 Win 7 Home Premium 64 位和 .Net 4.5 框架。我的开发机器是 Core 2 Duo。我在 Visual Studio 2011 Dev Preview 中开发。代码经过优化编译。

我无法在此处粘贴多行代码。任何人都可以开始告诉我为什么会发生这种情况/在我的代码中寻找什么。我对 .Net 程序集的结果感到有些震惊。

编辑

我测试了 MS 的 BlockingCollection 的速度,这也是 i5 速度的一小部分,但 4 个“核心”都是 100% = 某种类型的竞争条件。但是,在这里我只是调用 TryAdd() / Take() 方法,而我没有旋转或任何其他类型的线程控制。

【问题讨论】:

  • 将代码减少到绝对最小值,直到问题消失。然后给我们看代码。
  • 代码处于绝对最小值,不完全是几行。删除任何部分都会阻止整个事情做任何事情。这不会很有趣。
  • 多线程代码中的标准错误是竞争条件。触发此类错误的标准方法是更改​​执行时间。
  • 汉斯,真的。我将 SpinWait 与 Interlocked.CompareExchange 一起使用,这意味着据我所知,我应该没有竞争条件问题。
  • 'spinning', 'yields' ...我赞成最初仅使用内核同步对象来编写多线程应用程序(即,仅消息传递)。如果需要,一旦第一个内核锁定版本中的瓶颈经过最大浸泡测试,“旋转”应该作为性能优化保留。加载几天没有死锁,泄漏或任何其他异常行为,除了整体太慢。从未使用过 yield()、sleep(0)、sleep(1) 或发现有任何这样做的倾向。

标签: .net multithreading windows-7 cross-platform cpu


【解决方案1】:

您极有可能遇到竞争状况。症状都在那里——你有复杂的线程代码,要么没有运行,要么没有按照你期望的方式运行,并且行为因机器而异。它在双核机器上运行的事实并不能证明代码是无竞争的……更多的核心意味着出现微妙竞争的可能性更高。

总之,我们需要代码来帮忙。

您提到您正在使用“旋转类”——您是指 SpinLock 和 SpinWait 吗?

【讨论】:

  • 我将 SpinLock 与 Interlocked.CompareExchange 结合使用。虽然这可能会产生竞争条件,但我相信这是做我正在做的事情的最有效方式(由关于此类代码和 MSDN 的 albahari 教程提供支持)。但是,CPU 变为 0,这意味着什么都没有发生。这是无法解释的。
  • @Chris Shain:我认为死锁更有可能使 CPU 处于 0%,而不是数据竞争。
  • 是的,但他说有时(缓慢)有效,有时无效。那尖叫声向我跑来。也许一场比赛肯定会导致僵局。
  • @IanC,interlocked.compareexchange 是原子的,无需为此锁定。
  • @IanC:这两种方法是导致死锁的常见原因。如果没有线程在等待等待,则 Pulse 的信号丢失。您可能在此处遇到时间错误。尝试用 AutoresetEvent 替换它们。
【解决方案2】:

没有任何代码,我只能推测:

众所周知,Core i5 拥有 Intel 超线程技术,该技术仅使用 2 个内核将硬件线程数增加到 4 个,因此您实际上有四个线程竞争相同的 CPU 功能单元。这意味着计算密集型应用程序或需要大量内存带宽的应用程序在采用 HT 技术的 CPU 上使用时可能会出现性能下降。尝试将您的应用程序产生的线程数固定为 2(这样您实际上就没有使用 HT 功能)并查看它是否像在原始双核上一样运行。

还可以查看这篇文章了解 HT 的特性和弱点:http://software.intel.com/en-us/articles/performance-insights-to-intel-hyper-threading-technology/

还有这个(有点)相关的 SO 问题:Multithreaded Java does not speed up

【讨论】:

  • 代码甚至不能用 2 个线程运行。我正在使用 MS 的 spin 类,MSDN 指出它是专门为克服 HT 的弱点而设计的。我会查看您链接到的文章,看看是否有帮助。
  • @IanC:那你可能遇到了死锁。
  • 汉斯,我运行了一个更简单的代码版本和 MS 的 BlockingCollection。两者都完成了,但是 CPU 使用率很高,而且时间很糟糕。我固执地不使用 BlockingCollection 的任何线程控制,这意味着问题(至少在这种情况下)可能在我的代码之外。
  • @IanC:那么您的应用是否表现出该文章中提到的影响超线程 CPU 性能的任何特征?
猜你喜欢
  • 1970-01-01
  • 2015-11-27
  • 1970-01-01
  • 2018-08-28
  • 2021-08-21
  • 1970-01-01
  • 2012-07-04
  • 2015-01-26
  • 1970-01-01
相关资源
最近更新 更多