.net - 多线程资源争用

标签 .net multithreading profiling contention

我正在对运行有不同数量的允许线程的多线程程序进行性能分析。这是相同输入工作的三个运行的性能结果。

1 thread:
  Total thread time: 60 minutes.
  Total wall clock time: 60 minutes.

10 threads:
  Total thread time: 80 minutes. (Worked 33% longer)
  Total wall clock time: 18 minutes.  3.3 times speed up

20 threads
  Total thread time: 120 minutes. (Worked 100% longer)
  Total wall clock time: 12 minutes.  5 times speed up

由于花费更多的线程时间来完成相同的工作,因此我认为线程必须争用资源。

我已经检查了应用程序机器和数据库服务器上的四个支柱(cpu,内存,diskIO,网络)。内存是最初争用的资源,但现在已修复(始终有超过1G的空闲空间)。在20个线程的测试中,CPU徘徊在30%到70%之间,因此很多。在应用程序计算机上,diskIO实际上没有,而在数据库服务器上,diskIO很少。网络真的很棒。

我还使用redgate进行了代码剖析,看不到有任何方法在等待锁。这有助于线程不共享实例。现在,我正在检查更细微的项目,例如数据库连接建立/池化(如果20个线程尝试连接到同一数据库,它们是否必须彼此等待?)。

我正在尝试确定并解决资源争用,以便20个线程运行如下所示:
20 threads
  Total thread time: 60 minutes. (Worked 0% longer)
  Total wall clock time: 6 minutes.  10 times speed up

我应该寻找哪些最可能的来源(四大类别除外)?

每个线程执行的代码大约是:
Run ~50 compiled LinqToSql queries
Run ILOG Rules
Call WCF Service which runs ~50 compiled LinqToSql queries, returns some data
Run more ILOG Rules
Call another WCF service which uses devexpress to render a pdf, returns as binary data
Store pdf to network
Use LinqToSql to update/insert. DTC is involved: multiple databases, one server.

WCF服务在同一台计算机上运行,​​并且是无状态的,并且能够处理多个同时的请求。

机器有8个CPU。

最佳答案

您描述的是您想要100%的可伸缩性,即线程s的增加与挂锁时间的减少之间的1:1关系...这通常是一个目标,但很难实现...

例如,您写道没有内存争用,因为有1 GB可用空间...这是恕我直言的错误假设...内存争夺还意味着,如果两个线程尝试分配内存,则可能发生一个必须等​​待内存争用的情况。其他...要记住的另一个要点是GC发生的中断会暂时冻结所有线程... GC可以通过配置(gcServer)进行一些自定义-请参见http://blogs.msdn.com/b/clyon/archive/2004/09/08/226981.aspx

另一点是WCF服务,称为...如果无法按比例扩展(例如PDF渲染),那么这也是一种争用的形式...

可能发生争用的 list 是“无止境的” ...并且几乎始终不在您提到的显而易见的领域...

编辑-根据评论:

要检查的几点:

  • 连接池
    您使用什么提供者?如何配置?
  • PDF渲染
    可能的争用将在您使用的库中的某处进行度量...
  • Linq2SQL
    检查所有这些查询的执行计划...可能是某些查询采取了任何形式的锁定,因此可能创建了争用数据库服务器端...

  • 编辑2:

    线程
    这些线程来自ThreadPool吗?如果是这样,那么您将不会扩展:-(

    编辑3:

    ThreadPool线程不利于长时间运行的任务,在您的方案中就是这种情况。有关详细信息,请参阅
  • http://theburningmonk.com/2010/03/threading-using-the-threadpool-vs-creating-your-own-threads/
  • When to use thread pool in C#?
  • http://support.microsoft.com/kb/2538826
  • http://msdn.microsoft.com/en-us/magazine/dd252943.aspx

  • http://www.yoda.arachsys.com/csharp/threads/printable.shtml

    Long-running operations should use newly created threads; short-running operations can take advantage of the thread pool.



    如果您想要出色的性能,那么值得一看CQRS和描述为LMAX的真实示例。

    关于.net - 多线程资源争用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7831360/

    相关文章:

    c# - 在 C# WPF 中单击托盘通知后,第一次右键单击时不会打开上下文菜单?

    c# - 从连接字符串创建数据库的最简单方法?

    iOS GCD : Difference between any global queue and the one with background priority (DISPATCH_QUEUE_PRIORITY_BACKGROUND)?

    haskell - 为什么我的 Haskell 程序这么慢? Haskell 编程,人生游戏

    python - uwsgi + nginx背后的分析生产 flask 应用程序

    c# - RDLC 中递归数据的阶梯式报告

    c# - 重载方法如何工作

    c++ - std::move 堆栈对象(到不同的线程)

    c++ - QtConcurrent::run 正确使用

    node.js - 如何可视化 NodeJS .cpuprofile