我正在分析一个运行不同数量的允许线程的多线程程序。以下是同一输入工作的三次运行的性能结果。
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
由于需要更多的线程时间来完成同样的工作,我觉得线程必须争夺资源。
我已经检查过app机器和数据库服务器上的四个支柱(cpu,内存,diskIO,网络)。内存是最初的竞争资源,但现在已经修复(任何时候都超过1G)。在20线程测试中,CPU徘徊在30%到70%之间,因此很多。在应用程序计算机上,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。
答案 0 :(得分:3)
你所描述的是你想要100%的可扩展性,这是线程增加和wallcklock时间减少之间的1:1关系......这通常是一个目标,但很难达到......
例如,您写道没有内存争用,因为有1 GB可用...这是恕我直言错误的假设...内存争用还意味着如果两个线程尝试分配内存,可能会发生一个必须等待另一个...要记住的另一个问题是GC发生的中断暂时冻结所有线程...... GC可以通过配置(gcServer)进行一些定制 - 请参阅http://blogs.msdn.com/b/clyon/archive/2004/09/08/226981.aspx
另一点是WCF服务被称为...如果它无法扩展 - 例如PDF渲染 - 那么这也是一种争用的形式,例如......
可能的争用列表是“无休止的”......并且几乎不会总是在你提到的明显区域......
编辑 - 根据评论:
要检查的一些要点:
编辑2:
<强>线程
强>
这些线程来自ThreadPool吗?如果是这样,那么你就不会缩放: - (
编辑3:
ThreadPool线程对于长时间运行的任务是不利的,在您的场景中就是这种情况......有关详细信息,请参阅
来自http://www.yoda.arachsys.com/csharp/threads/printable.shtml
长时间运行的操作应该使用新创建的线程; 短期运行可以利用线程池。
答案 1 :(得分:2)
不是测量总线程时间,而是测量执行某些操作的操作的时间(数据库,磁盘,网络等)。
我怀疑你会发现当你有更多的线程时,这些操作需要更长的时间,这是因为争用是在那个I / O的另一端。例如,您的数据库可能正在序列化数据一致性请求。
答案 2 :(得分:2)
如果任何地方有任何类型的同步,那么这也是一个竞争资源。如果有任何 I / O,那就是竞争资源。
从1线程到N线程时,你永远不会看到N x加速。这是不可能的,因为最终,CPU中的所有是一个共享资源,会有一定程度的争用。
有很多因素阻止您获得全线性加速。您假设数据库,运行数据库的服务器,将其连接到客户端的网络,客户端计算机,两端的操作系统和驱动程序,内存子系统,磁盘I / O和所有内容< / em>介于两者之间时,从1到20个线程可以快20倍。
两个字:梦想。
这些瓶颈中的每一个都只能让你减慢几个百分点,然后整体结果会像你所看到的那样。
我相信你可以调整它以更好地扩展,但不要指望奇迹。
但您可能会寻找的一件事是缓存线共享。线程是否访问与其他线程使用的数据非常接近的数据?你多久可以避免这种情况发生?