2010-12-22 113 views
1


我的应用程序使用了很多关键部分,我想知道它们中哪些可能会导致较高的争用。我想避免瓶颈,以确保可扩展性,特别是在多核,多处理器系统上。
我发现一个意外的时候,当我注意到应用程序在重负载下等待进入临界区时出现许多线程挂起。这很容易解决,但是如何在它们成为真正的问题之前检测这样的高争用关键部分?
我知道有一种方法可以创建完整转储并从中获取该信息(以某种方式?)。但这是相当侵入性的方式。应用程序可以使用方法来诊断自己是否存在这些问题?
我可以使用来自结构_RTL_CRITICAL_SECTION_DEBUG的数据,但有一些注意到这可能是不安全的跨不同的Windows版本:http://blogs.msdn.com/b/oldnewthing/archive/2005/07/01/434648.aspx
有人可以建议一个可靠的,而不是太复杂的方法来获得这样的信息?如何检测高争用临界区?

回答

-1

你在说什么在测试过程中非常有意义,但在生产代码中并不可行。

我的意思是......你可以在生产代码中做某些事情,比如确定LockCount和RecursionCount值(这是记录的),从LockCount中减去RecursionCount并且presto,你有等待他们的手的线程数CRITICAL_SECTION对象。

你甚至可能想要更深入。 SDK中记录了RTL_CRITICAL_SECTION_DEBUG结构。关于这种结构唯一改变的是一些保留字段被赋予名字并被使用。我的意思是..它在SDK头文件(winnt.h)中,记录的字段不会改变。你误解了Raymond的故事。 (他有点过错,他和下一个人一样喜欢轰动。)

我的一般观点是,如果您的应用程序中存在严重的锁争用,您应该通过一切手段将其揪出来。但是如果可以避免的话,千万不要让代码在关键部分更大。读取调试结构(甚至是lockcount/recursioncount)应该只在你持有对象时才会发生。在调试/测试版本中没问题,但它不应该投入生产。

+0

当然,这不是生产代码,这是一个调试的事情。 我不是要求建议如何改进同步以避免争用。我可以处理。我在寻求帮助来确定需要优化的东西。我有几十个关键部分。其中一些很少使用,其他可能会引起争议。我想将应用程序置于压力测试之下,看看哪些关键部分是瓶颈。 所以,你说RTL_CRITICAL_SECTION_DEBUG被记录。你的意思是它在SDK头?因为我无法在MSDN文档中找到它。 – jesse 2010-12-22 02:15:56

0

除了关键部分(即信号量)之外,还有其他方法可以处理并发。最好的方法之一是非阻塞同步。这意味着构建代码即使使用共享资源也不需要阻塞。你应该仔细阅读并发性。此外,您可以在此发布代码段,并且有人可以为您提供如何改进并发代码的建议。

0

看看英特尔线程档案器。它应该能够帮助发现这些问题。

此外,您可能希望通过将临界区域封装在将数据转储到磁盘上进行分析的代理来检测代码。它真的取决于应用程序本身,但它可能至少是线程等待CS的时间。

+0

线程事件探查器是一个功能强大的工具,但我需要一个轻量级的方法,而无需整理代码。 我想我会使用RTL_CRITICAL_SECTION_DEBUG.ContentionCount。 – jesse 2010-12-22 02:40:51