Visual C++优化对大型数据集合的并发访问
2010-08-22 20:47:32 来源:WEB开发网使用单个临界区时,随着线程数目的增加,用于执行固定次数迭代的时间显著增加。这是因为单个临界区使得线程过于频繁地进行上下文切换,并且 CPU 花费过多的时间在内核模式下执行上下文切换代码。
您可以在 Windows NT 或 Windows 2000 上通过 Performance Monitor 应用程序证实这一点。在 Windows NT 上,您可以在 Start | Programs | Administrative Tools 下找到它。从 Edit 菜单中选择 Add to Chart,将性能对象设置为 System,然后将以下三个跟踪标志添加到您的图表中:% Total Processor Time、% Total Privileged Time 和 Context Switches/sec。在 Windows 2000 上,概念是一样的,但 Redmondtonians(指 Microsoft)已经改变了组件的位置。Performance Monitor 位于 Control Panel 中的 Administrative Tools 下面。单击工具栏上的大加号,将性能对象设置为 Processor,再添加跟踪标志 % Processor Time 和 % Privileged Time。然后,将性能对象设置为 System 并添加 Context Switches/sec。
当您运行 ConcurrencyDemo 时,您将看到在使用大量辅助线程的单个临界区测试期间,特权时间量和上下文切换的次数都大大增加了。与此相反,使用临界区表的测试将执行少得多的上下文切换,从而得到相当稳定的执行时间,如图 14 所示。
图 15 多 CPU 计算机上的结果
四 CPU 计算机上的结果更加令人吃惊(参见图 15)。使用单个临界区时的趋势在最初因为线程数从一个增加为两个而增加以后,变得相当稳定。请注意此处与单 CPU 计算机上的单个临界区情形完全不同的行为。四 CPU 计算机无须疲于应付上下文切换的原因在于,在多 CPU 计算机上,临界区具有一个“旋转计数”。这意味着当一个线程试图获取已经锁定的临界区时,该线程将在循环中“旋转”一会儿,检查该锁是否已被释放,然后进入休眠状态。这是有利的,因为休眠会导致上下文切换,其代价要比浪费在旋转上的周期更大。
使用临界区表时,随着您使用的线程数从一个增加到四个,执行时间会急剧下降(70% 以上)。这表明全部四个 CPU 正在并行工作,以获得最佳的并发性。(实际上,理论上的最佳并发性将显示执行时间下降 75%,但完全按线性比例下降是很罕见的。)请注意,随着您使用的线程数超过四个,性能将会因为上下文切换更为频繁而下降。这表明了使用 I/O 完成端口以使正在运行的线程数非常接近 CPU 个数的重要性。
小结
本文介绍的用于提高并发性的技术具有许多应用。我首先在一个服务器应用程序上设计了这一技术,该应用程序使用 C++ 智能指针并通过引用计数对象实现了垃圾回收。我用临界区表保护了该引用计数。(您可能认为我可以使用 InterlockedXxx 系列函数达到这一目的,但是将引用计数递减到零以及删除该对象的操作必须是需要临界区的原子操作。)
还可以使用临界区表来克服 CD 示例中数据库的一个主要局限,即无法以线程安全且具有高度并发性的方式在该数据库中添加或删除项。创建具有高度并发性的集合是一项艰难的任务,并且超出了本文的范围,但在我已经发现的问题的一个解决方案中,临界区表是一个重要的组件。
我希望您将在自己的服务器应用程序中找到这一技术的用武之地。如果您确实这样做了,那么我非常愿意了解相关情况。
本文配套源码
- ››Visual Basic 2008 数学函数
- ››Visual Studio2005中Smart Device的问题
- ››Visual Studio 中根据数据库字段动态生成控件
- ››Visual Studio 11全新黑色主题
- ››Visual Studio 2011 Beta新特性(一):安装VS201...
- ››Visual Studio自定义调试窗体两个小技巧
- ››Visual Studio 2005 Team Edition for Database P...
- ››Visual C#两分钟搭建BHO IE钩子
- ››Visual C++优化对大型数据集合的并发访问
- ››优化精髓之商业性网站常遇见的问题和误区
- ››大型网站的域名分布策略
- ››优化增强您的Visual C++应用程序
更多精彩
赞助商链接