胃力胶囊饭前还是饭后:多核编程中的线程分组竞争模式

来源:百度文库 编辑:九乡新闻网 时间:2024/04/29 05:02:34
多核编程中的线程分组竞争模式
 在多核编程中,锁竞争导致的CPU饥饿现象是引起多核CPU性能无法发挥的最重要原因之一,在多核编程中的锁竞争难题一文中已经讲过锁竞争对性能的影响,如何消解锁竞争导致的CPU饥饿现象成了迫切需要解决的问题。目前业界发展的无锁编程技术可以有效降低锁竞争引起的性能下降问题,无锁编程主要是采用原子操作来替代锁,只存在原子操作竞争问题,由于原子操作只是一条指令,速度非常快,因此可以近似地看成是无锁竞争的,除非原子操作非常频繁。无锁编程难度非常高,从目前的情况来看,普通程序员要亲自进行无锁编程是不现实的事情。并且目前只有少数数据结构可以实现无锁编程,从目前商用的无锁编程库NOBLE来看,只提供了队列、栈、链表、词典、带引用计数的垃圾回收内存管理等少数几种无锁编程结构,只能解决部分锁竞争问题,这个库的售价高昂,以下是从NOBLE的网站上拷贝下来的售价。
$1395 USD, NOBLE Professional Edition, Evaluation License 1 Months, Windows
$3295 USD, NOBLE Professional Edition, Evaluation License 3 Months, Windows看了这个售价,估计国内也没有多少公司愿意出这么高昂的价钱的购买这个一个功能有限,且使用起来不像以前的使用锁的库那么方便的库。既然没有无锁编程的免费午餐可以享用,那么使用锁来编程的话,可不可以避免锁竞争导致的CPU饥饿现象呢?答案是可以的,这就是文章标题中的线程分组竞争模式,它使用锁来进行保护共享数据,但是又避免了锁竞争时出现CPU饥饿现象。其实这个模式在业界已经有了很成功的实践,那就是队列池。当然这个模式的应用不仅仅限于队列池,也可以用到很多其他的满足一定条件的共享数据保护上。先看一下线程分组竞争模式的基本思想,所谓线程分组竞争就是将线程分成若干个组,每个组的线程间存在锁竞争,但是不同组之间的线程不存在锁竞争。下图以添加操作和删除操作作为示例来显示2个分组线程竞争的情况:  图中显示了两个分组的线程竞争情况,共有四个线程分成两组进行竞争,添加操作线程1和删除操作线程1之间存在锁竞争情况,添加操作线程2和删除操作线程2之间存在锁竞争情况,但是添加操作线程1(或删除操作线程1)和添加操作线程2和删除操作线程2之间不存在锁竞争。在这种分组锁竞争模式下,任意一组线程中,至少有一个线程在执行,因此如果有N组线程的话,那么至少有N个线程在执行,如果N大于等于CPU的核数,那么任意一个CPU     核上都有线程一直在运行,可以充分保证CPU不会产生饥饿现象。 并不是任意共享数据都可以采用线程分组竞争的形式来进行访问,共享数据必须可以分成若干个独立的子数据,每次操作只需要操作某个子数据,一次操作中不需要操作多个子数据。线程分组竞争模式和无锁编程相比,有着很大的优势,最重要的优势有两点:一、使用有锁编程,编程难度很小,易于为普通程序员掌握。二、并发性比无锁编程更好,无锁编程中存在原子操作竞争问题,其竞争激烈程度会随CPU核数增加而增加,特别是当原子操作包含在大循环中时,原子操作竞争最坏情况下会使性能降到和单核CPU一样。而线程分组模式中各个CPU核完全是并行运行的,CPU核相互间不存在竞争问题,因此CPU核数增加不会造成任何影响。以上讲的是线程分组竞争模式的一种情况,实际情况中很多情况和这种模式并不完全符合,因此线程分组模式存在一些变种以适应更多的实际情况。下图便是一个最常见的变种:  如上图所示,在这个变种中添加操作线程只有一个,而删除操作线程却有两个,添加操作线程A如果操作子内存区域1,则使用lock1,操作子内存区域2时则使用lock2。添加操作线程A可以和删除操作线程1和删除操作线程2存在锁竞争,但是删除操作线程1和删除操作线程2之间不存在锁竞争。从运行情况来看,3个线程中至少有2个在同时运行,如果有N个子内存区域和N个删除操作线程的话,那么至少有N个线程在同时运行,因此这种锁竞争模式中,同样可以保证当CPU核数少于等于线程分组的个数时,不会发生CPU饥饿现象。队列池便是这种模式的一个很好的成功实践。线程分组竞争模式是消除锁竞争造成多核CPU性能下降的最有效方式,它的性能近似于单核CPU中的多线程编程的性能,这种模式也是设计本地分布式数据结构的一种有效方法。参考资料:[1]《并行编程模式》Timothy Mattson等著 敖富江译[2]《多核程序设计技术》Shameem Akhter等著 李宝峰等译[3]《并行程序设计》 Barry Wilkinson, Michael Allen著,陆鑫达等译[4]“ NOBLE: A Non-Blocking Inter-Process Communication Library.”  H. SUNDELL, P. TSIGAS. Proceedings ofthe 6th Workshop on Languages, Compilers and Runtime Systems for Scalable omputers (LCR’02), Lecture Notes in Computer Science, Springer Verlag, 2002.[5] http://www.nobel.org/ 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/drzhouweiming/archive/2007/07/10/1684753.aspx
多核编程中的线程分组竞争模式 多核编程中的线程随机竞争模式的概率分析 Windows核心编程(第五版)笔记 第八章 用户模式下的线程同步(Thread Sync... Java中的线程组 C#多线程编程:线程的启动 多核系统中三种典型锁竞争的加速比分析 线程共享进程中的数据 多核系统中三种典型锁竞争的加速比分析 - 周伟明的多核、测试专栏 - CSDN博客 多线程编程之四——线程的同步 Linux之线程同步篇|Linux,线程同步-中国源码网: 开放源代码&&编程 多核编程的几个难题及其应对策略(难题一) FastFlow 1.1.0 发布,多核编程框架 - CSDN.NET - CSDN软件研... 浅谈线程池(中):独立线程池的作用及IO线程池 - 老赵点滴 - 追求编程之美 - 博客园 vc中的XML编程心得 模式就是企业的竞争工具 多线程编程之三——线程间通讯 - VC知识库文章 200行C代码实现简单线程池 - Linux内核编程 - 举世无双的学习之路 Windows核心编程(第五版)笔记 第六章 线程基本概念(Thread Basics) Windows核心编程(第五版)笔记 第九章 利用内核对象同步线程(Thread Sync... Windows核心编程(第五版)笔记 第十一章 线程池(The Windows Threa... 秋风:欢迎广东模式、重庆模式的竞争 秋风:欢迎广东模式、重庆模式的竞争 浅谈线程池(下):相关试验及注意事项 - 老赵点滴 - 追求编程之美 - 博客园 ASP.NET编程中的十大技巧