Presentation is loading. Please wait.

Presentation is loading. Please wait.

多线程编程基本概念 2008.

Similar presentations


Presentation on theme: "多线程编程基本概念 2008."— Presentation transcript:

1 多线程编程基本概念 2008

2 并行硬件 多处理器:Multiprocessors 超线程:Hyper threading 双核:Dual-Core
SMP,Symmetrical Multi-Processing,多路对称技术,要求CPU必是2n个,如2,4,8,16 超线程:Hyper threading 双核:Dual-Core 多核:Multicore FPGAs:Field Programmable Gate Arrays

3 多处理器 多处理器指的是多个CPU不在同一个芯片当中 1990年代,主要用于服务器,采用刀片式处理器板组合多个CPU
现在多处理器都是通过高速通信接口集成在一个主板上,例如:典型的IBM服务器系列 MMU:内存管理单元 缺点:昂贵

4 超线程 所谓超线程技术就是利用特殊的硬件指令,把多线程处理器内部的两个逻辑内核模拟成两个物理芯片,从而使单个处理器就能“享用”线程级的并行计算的处理器技术,负责处理第二个线程的那个逻辑处理器,其使用的是仅是运行第一个线程时被暂时闲置的处理单元 当一个逻辑处理器在执行浮点运算(使用处理器的浮点运算单元)时,另一个逻辑处理器可以执行加法运算(使用处理器的整数运算单元) Intel的技术,但AMD和Intel打过超线程的专利官司 超线程本质上是一个CPU,目的只不过是提升多线程代码的效率,提升效率约30% P4是典型

5 双核和多核 多个处理器单元集成在一个芯片当中,典型是2、4、8个 多核的问题在于程序编码 性能提升最简单的方式:多线程
AMD的多核CPU中有一个仲裁机构,Intel的好像没有 仲裁机构主要负责判定那个主控模块(CPU)(总线控制权申请者),获得下一个总线传输周期的总线控制权

6 双CPU VS. 多核 内存管理 Cache 通信

7 FPGAs 现场可编程门阵列 用于大规模的硬件设备或适合高性能数值运算,例如DSP应用 FPGAs比微处理器运行时钟频率低,并且功耗大

8 多任务 Multitasking 多任务OS,如Windows XP
多任务是指操作系统能够在多个任务之间快速切换,给人的印象是不同的应用程序正在同时进行,CPU时钟越快,多任务运行也就越流畅 单核和多核下的多任务是不一样的 单核下的多任务是串行的,多核下的多任务是并行的,多核下的多任务更有效率

9 多线程 MultiThreading和多核
请问多核下的多线程是否一定就会提升运行效率?

10 绑定CPU 在多CPU下运行有问题的程序的简单的解决方法:绑定CPU,SetProcessAffinityMask

11 提升性能的途径 操作系统:操作系统分析指令,对可以并行执行的指令指配到不同CPU,难度较大,目前OS做到可以分配不同线程,还做不到把不同代码段指配道不同CPU 编译器:难度较大,目前不现实,编译器智能分析代码,对编译的代码能够支持多核 库函数:难度大,有一部分库函数可以利用如Win32线程库,OpenMP,包括Intel提供的相关库函数 程序代码:自己编写多线程,重构代码,目标性能提升非常显著,对程序员要求高

12 针对多CPU的优化例子 function Test1(): Boolean; var   i : Integer; begin   for i := 0 to 50000 do   begin     // Do something....   end; end; function Test(): Boolean; var   i : Integer; begin   for i := 0 to 100000 do   begin     // Do something....   end; end; function Test2(): Boolean; var   i : Integer; begin   for i := 50001 to 100000 do   begin     // Do something....   end; end;

13 讨论? 右边的代码是否可以优化? X,Y为独立的变量 Result := (x *100) + (y / 1234)

14 Amdahl 定理 Amdahl 定理:描述了任意给定代码所能实现加速比的理论可能性
对于串行代码比例占S的代码,理论上可以在 N个处理器上实现的最大加速比为:1/(S+(1-S)/N)。 比如串行代码占20%的代码,在4核处理器上可以实现的最大加速比为1/(20%+(1-20%)/4)=2.5。 推论:加速比受限于代码中串行代码的比例

15 同步和异步 同步synchronous 和异步asynchronous 阻塞Blocking和非阻塞Non-Blocking
串行(serial)和并行(parallel ) 不同地方同步和异步说法不太一样,但含义一样: 同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回 异步就是100个人同时做一件事,同步就是100个人排队做一件事

16 锁 Lock 冲突:Conflict,对同一个资源的访问冲突 解决冲突的方法:锁 各个实现的对象,范围不一样,代价也不一样,性能也不一样
信号量:Semaphore ,常用,全局 临界区:critical section,常用,进程内 互斥量:Mutex,常用,全局 事件:Event,全局 可等待定时器:waitable timer 各个实现的对象,范围不一样,代价也不一样,性能也不一样

17 多线程和消息处理 Win32中,消息处理过程是运行在窗口创建的时候的线程当中的 *****非常重要的一点 讨论:
有一线程A,在创建的时候Create一个窗口W,另外有一个线程B,在其运行当中,接收到W句柄,然后利用W处理消息,请问如果线程A销毁了,B是否还可以正常运行?

18 线程池 Thread Pooling 线程创建和销毁是有巨大开销的?为什么? 如果需要频繁地、不停创建线程并销毁,那么请使用线程池来解决

19 优先级 进程优先级(priority class) 线程优先级(priority level ) 请问:
高于正常,低于正常,极高,空闲,正常,实时 线程优先级(priority level ) 高于正常,低于正常,最高,空闲,最低,正常,实时,总共有16级可以设置 线程的优先级同时由进程优先级和线程优先级决定,组合起来总共32级,0(Idle)~31(实时) 请问: Idle Priority Class的进程中的一个Real Time Thread出现什么情况?那么Real Time Class中的Idle Thread呢? 占用CPU最高的是什么?最低的是什么?

20 优先级 优先级的调整 优先级使用规则 SetThreadPriority SetPriorityClass
越是高优先级运行的代码,越要简洁,运行时间越短越好 周期性的更新的,使用低优先级 高优先级用于需要实时响应的功能 根据需要临时提升和降低优先级

21 加锁原则 加锁必须遵循最小原则,即最后关头才Lock,一旦使用完毕,不造成冲突的情况下,立即UnLock
自己检查你的设计和代码,很多情况下甚至连锁都可以不需要的

22 讨论? 有一个全局整数变量G,只有一个线程A,需要修改变量G,另有其他线程T1,T2,T3等,仅读取变量,请问是否需要加锁?
如果全局变量为TList或者其他TObject对象,那又如何? 原子操作的概念:Atom 原子操作无需加锁,因为原子操作是不可分割的

23 瓶颈 现在的技术当中,瓶颈在于内存,I/O总线,硬盘系统 编程当中的瓶颈在于对同一个资源的加锁访问 减少瓶颈,优化瓶颈可以最有效提升性能

24 讨论? 如果一段代码,每秒钟可以处理100MB数据,那么在现有的主流硬件条件下,能否通过多CPU和多线程支持进一步提升性能?那么每秒钟20MB的能力又怎么样呢?

25 多线程程序设计原则 独立的海量计算应该作为独立线程运行 独立的数据处理应作为独立线程运行 海量I/O应该由同一个线程运行
Socket层应该独立一个线程运行 线程中尽可能减少堆上的内存分配?请问栈上呢? 绝对小心全局变量的使用 多线程程序应该在多CPU系统上运行测试,避免单CPU系统对多线程的时序化掩盖问题

26 多线程编程的常见问题 死锁:死锁是多线程中常见的问题
死锁一个是通过调试解决 一个是死锁拆除技术 调试困难,有时候把IDE都可能挂死,新的IDE一般可以冻结Freeze整个应用程序,所以调试问题还是可以解决的 利用Log输出是最简单有效的方式,在加锁和解锁的地方输出一些信息即可 利用Process Explorer设定线程,VC的调试器可以直接设定运行线程的状态

27 死锁例子 数据服务,解码子进程死锁 数据服务针对每个RCU创建一个Window,处理消息,收到Socket发送的数据后,通过SendMessage发送消息给子进程窗口Sub,Sub收到消息后,对数据进行处理,解码后发送SendMessage回主进程W,结果死锁

28 下面代码会有死锁吗? class TAList FList: TList; procedure Lock;
procedure Unlock; procedure Add(Value: Integer); function GetValue(index: Integer); end; function TAList.GetValue() if (Index > 0) and (Index < FList.Count) then Result = FList[Index] else raise error "out of bounds" procedure TAList.Add(Value: Integer); begin FList.Add(Value); procedure DeakLock(List1, List2: TAList); var V : Integer; begin List1.Lock; List2.Lock; try V := List.GetValue(10); List2.Add(V); finally List1.UnLock; List2.UnLock; end; FirstList, SecondList: TAList; 线程A:DeadLock(FirstList, SecondList); 线程B:DeadLock(SecondList, FirstList);

29 死锁原因 当一段代码需要两个或更多资源时,都有潜在死锁阴影 死锁仲裁算法,非常复杂,最好方式是找出一种策略,确保死锁不会发生
All-or-Nothing策略:要不统统获得,要不统统没有,防止死锁发生 讨论:如何解决上一个页面中的死锁问题?

30 解决方案? 利用Mutex取代Critical Section,配合WaiForMultipleObjects使用 修改代码结构
再增加临界区?把List1.Lock;List2.Lock作为不可分隔的操作原子? ……

31 临界区Lock 请问临界区是否是内核对象? 临界区是同一个进程内最常见的进程同步手段
Lock和UnLock无论何时何地都要保证配对,所以Lock和UnLock一定要用Try Finally

32 例子 题外话:Win32中,内核对象一般要Create,有句柄(Handle) 例如CreateMutex,CreateEvent,……
var CR : TRTLCriticalSection; procedure ThreadProc; begin EnterCriticalSection(CR); try Sleep(5000); finally LeaveCriticalSection(CR); end; procedure TForm1.btn1Click(Sender: TObject); ID: Cardinal; FThread := CreateThread(nil, nil, CREATE_SUSPENDED, ID); ResumeThread(FThread); procedure TForm1.btn2Click(Sender: TObject); begin EnterCriticalSection(CR); end; procedure TForm1.btn3Click(Sender: TObject); LeaveCriticalSection(CR); procedure TForm1.FormCreate(Sender: TObject); InitializeCriticalSection(CR); 不对称的Lock/UnLock会导致无休止的等待 题外话:Win32中,内核对象一般要Create,有句柄(Handle) 例如CreateMutex,CreateEvent,……

33 死锁检测 利用一些API,进行预先检测,例如: TryEnterCriticalSection 可以利用一个循环超时检测来判断是否有死锁发生

34 常见同步API 临界区:DeleteCriticalSection,InitializeCriticalSection,EnterCriticalSection,LeaveCriticalSection,TryEnterCriticalSection 事件:CreateEvent,OpenEvent,PulseEvent, ResetEvent,SetEvent 互斥量:CreateMutex ,OpenMutex,ReleaseMutex 信号量:CreateSemaphore ,OpenSemaphore,ReleaseSemaphore 同步等待函数:WaitForSingleObject,WaitForMultipleObjects等,支持的对象包括:Event,Job,Mutex,Process, Semaphore, Thread, Waitable timer等等

35 讨论? VCL是如何同步的?

36 用法示例 创建:FHandle := CreateEvent(EventAttributes, ManualReset, InitialState, PChar(Name)); 加锁: WaitForSingleObject(Handle, TimeOut); ResetEvent(Handle); 解锁 SetEvent(Handle);

37 同步机制摘要 Critical Section:排他性占有,单进程多线程 Mutex:不同线程(可跨进程)排他性占有
局部对象,非内核对象 快速,高效 同一时刻只有一个临界区可以等待 无法检测是否已经被某个线程放弃 Mutex:不同线程(可跨进程)排他性占有 内核对象,可以有名字,跨进程 Mutex有Owner(拥有者),只能被拥有者释放 用Wait……等待 Semaphore:追踪有限的资源 内核对象,没有拥有者,可以有名字 可被任何线程释放 Mutex相当于信号量计数为1的Semaphore Event:常用于重叠I/O 内核对象,可以有名字,跨进程 程序完全控制,用于设计新的同步对象 “激活”请求可能不会被保存,可能会丢失

38 利用多CPU进行海量数据处理

39 线程模型 单线程,利用重叠I/O,尽可能让CPU和磁盘忙碌
每个Client一个线程,对于少的Client比较好,缺点:超过1000个Client会死得很难看 每个CPU一个线程,可以均衡负载,配合完成端口I/O,完成端口属于另外一个复杂的话题,此处不予讨论

40 并行计算 并行平台的通信模型: 共享数据(POSIX、windows线程、OpenMP)、消息交换(MPI、PVM)
并行算法模型:   数据并行模型、任务依赖图模型、工作池模型、管理者-工作者模型、消费者模型 对于并行计算一个任务可能涉及到的问题:   任务分解、任务依赖关系、任务粒度分配、并发度、任务交互 并行算法性能的常见度量值:     并行开销、加速比、效率(加速比/CPU数)、成本(并行运行时间*CPU数)

41 参考资料 《Win32多线程程序设计》,侯捷翻译,强烈推荐,对多线程编程以及各个概念说明的非常透彻,对各个同步对象有详细描述
MSDN:Synchronization Functions


Download ppt "多线程编程基本概念 2008."

Similar presentations


Ads by Google