【发布时间】: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