基于多核系统的编程技术 第一节 并行.ppt
《基于多核系统的编程技术 第一节 并行.ppt》由会员分享,可在线阅读,更多相关《基于多核系统的编程技术 第一节 并行.ppt(100页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、基于多核系统的编程技术第一节 并行程序设计流程第二节 线程API多核架构及编程技术内容1并行程序设计流程2线程API3OpenMP4一些并行程序设计问题的解决办法1.1基本概念进程(Process)进程(process)离散的程序任务集合。一个进程包括:进程ID,进程组ID,用户ID,组ID;环境工作目录程序指令寄存器堆栈(Stack)堆(Heap)文件描述符信号操作共享库进程间通信工具消息队列、管道、信号量、共享内存UNIX下进程示例下进程示例1.1基本概念线程(thread)是一些相关指令的离散序列。从硬件资源上讲,线程就是一条与其它硬件线程执行路径相互独立的执行路径。操作系统的工作就是讲
2、软件线程映射到硬件执行资源上。每个线程有自己的:堆栈指针寄存器调度策略(如优先级)线程自有数据一个进程内的线程示例一个进程内的线程示例对于在一个进程内的线程:对于在一个进程内的线程:一个线程对共享的系统资源进行修一个线程对共享的系统资源进行修改,其它这个进程内的其它线程也可改,其它这个进程内的其它线程也可以见到这种修改。以见到这种修改。对于同一个数据,可能有两个值相对于同一个数据,可能有两个值相同的指针指向这个数据。同的指针指向这个数据。进程内的多个线程可以对同一个内进程内的多个线程可以对同一个内存单元进行读和写操作,所以必须要存单元进行读和写操作,所以必须要采取显式同步机制。采取显式同步机制
3、。在同一个进程的地址空间下,线程在同一个进程的地址空间下,线程间的通信消耗更小。间的通信消耗更小。进程与线程程序在操作系统中作为进程方式存在、获取资源、运行。在一个进程内,线程可以创建其它线程。每个线程有各自的栈(stack)。一个进程内所有的线程共享代码段和数据段。多核与并行的关系可以在多核平台上实现真正的并行。在各个核上可以实现并发。线程的特点优点:(为什么要使用线程)增强性能特别在多核平台上资源利用充分有效数据共享缺点:增加程序编写难度,增加程序复杂度。难以调试。优点缺点。线程的层次用户级线程(User-levelthreads)在应用软件中所创建和操纵的线程。内核级线程(Kernel-
4、levelthreads)操作系统实现大多数线程的方式。硬件线程(Hardwarethreads)线程在硬件资源上的表现形式。线程计算模型用户级线程用户级线程由可执行应用程序使用,同时由用户级操作系统管理由可执行应用程序使用,同时由用户级操作系统管理内核级线程内核级线程由操作系统内核使用,同时由内核操作系统处理由操作系统内核使用,同时由内核操作系统处理硬件线程硬件线程由每个处理器使用由每个处理器使用执执 行行 流流 程程执行环境中的线程执行流程线程定义和准备线程定义和准备线程运行线程运行线程执行线程执行由程序设计环境由程序设计环境和编译器完成和编译器完成由操作系统采用由操作系统采用进程完成进程
5、完成由处理器完成由处理器完成用双向箭头表示线程在执行用双向箭头表示线程在执行之后将结果返回到用户空间之后将结果返回到用户空间操作系统内部的线程操作系统被分为两个截然不同的层次:用户级(运行应用程序的层次)内核级(系统行为发生的层次)内核级是操作系统的核心,维护着大量用于追踪进程和线程的表格。内核级线程能够提供更高的性能。并且同一进程中的多个内核线程能够同时在不同的处理器或者执行核上执行。如OpenMP,PThread等线程库用内核级线程。硬件上的线程软件线程的指令都是由硬件来实际执行的。硬件上的多线程技术需要多个CPU来增加并行性。(每个线程都在独立的处理器上运行)多核CPU提供了两个或更多的
6、执行核,能够支持真正的硬件多线程技术。1.2并行程序设计方法(5种)显式线程(Explicitthreading)微软Windows线程API,Pthreads,Java线程类等。利用编译器指导(Compiler-directed)自动并行,OpenMP,IntelThreadingBuildingBlocks等利用并行数学库(Parallelmathlibraries)IntelIPP/MKL,ScaLAPACK,PARDISO,PLAPACK并行程序语言有150种以上消息传递(Messagepassing)MPI,OpenMP,PVM,等等。并行程序设计流程 分析分析分析分析VTune P
7、erformance Analyzer设计设计设计设计 (Introduce Threads)(Introduce Threads)Intel Performance libraries:IPP and MKLOpenMP*(Intel Compiler)Explicit threading(Win32*,Pthreads*)调试错误调试错误调试错误调试错误Intel Thread CheckerIntel Debugger性能分析和调整性能分析和调整性能分析和调整性能分析和调整Intel Thread ProfilerVTune Performance Analyzer内容1并行程序设计流程
8、2线程API3OpenMP4一些并行程序设计问题的解决办法微软Win32/MFC线程API微软.NET框架的线程APIPOSIX线程2.1微软的多线程API在Windows操作系统上开发多线程应用程序员的有力工具。包括:Win32/MFC线程API微软.NET框架的线程API2.1.1微软Win32/MFC线程API创建线程管理线程使用Windows事件进行线程通信线程同步原子操作线程池线程优先级处理器亲和带有纤程支持的用户级线程机制Windows多线程应用程序的编译和链接线程创建与终止方法创建线程终止线程HANDLE CreatThread(LPSECURITY_ATTRIBUTES lpT
9、hreadAttributes,/数据结构数据结构SIZE_T dwStackSize,/堆栈大小堆栈大小LPTHREAD_START_ROUTINE lpStartAddress,/指向线程实际运行指向线程实际运行 /代码的指针代码的指针LPVOID lpParameter,/传递给线程函数的值传递给线程函数的值DWORD dwCreationFlags,/指定多个配置选项指定多个配置选项LPWORD lpThreadID);/线程唯一标志:线程线程唯一标志:线程 /ID的地址。的地址。VOID ExitThread(DWORD dwExitCode);线程创建使用C运行库时unsigned
10、 long _beginthread(void(_cdecl*start_address)(void*),unsigned stack_size,void*arglist);unsigned long _beginthreadex(void*security,unsigned stack_size,unsigned(_stdcall*start_address)(void*),void*arglist,unsigned initflag,unsigned*thrdaddr);void _endthread(void);void _endthreadex(unsigned retval);线程创
11、建使用MFC库时CWinThread*AfxBeginThread(AFX_THREADPROC pfnThreadProc,LPVOID pParam,int nPriority=THREAD_PRIORITY_NORMAL,UINT nStackSize=0,DWORD dwCreateFlags=0,LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);void AfxEndThread(UINT nExitCode);管理线程控制线程的执行DWORD SuspendThread(HANDLE hThread/handletothethread);DWO
12、RD ResumeThread(HANDLE hThread/identifiesthreadtorestart);BOOL TerminateThread(HANDLE hThread,/handletothethread DWORD dwExitCode/exitcodeforthethread);使用Windows事件进行通信BOOL SetEvent(HANDLE hEvent/handletoeventobject);BOOL ResetEvent(HANDLE hEvent/handletoeventobject);HANDLE CreateEvent(LPSECURITY_ATT
13、RIBUTES lpEventAttributes,BOOL bManualReset,/flag for manual-reset event BOOL bInitialState,/flag for initial state LPCTSTR lpName/pointertoevent-objectname);HANDLE OpenEvent(DWORD dwDesiredAccess,/access flag BOOL bInheritHandle,/inherit flag LPCTSTR lpName/pointertoevent-objectname);BOOL PulseEven
14、t(HANDLE hEvent/handletoeventobject);DWORD WaitForSingleObject(HANDLE hHandle,/handletoobjecttowaitforDWORD dwMilliseconds/time-outintervalinmilliseconds);返回值:WAIT_ABANDONEDWAIT_OBJECT_0WAIT_TIMEOUTWAIT_FAILEDDWORD WaitForMultipleObjects(DWORD nCount,/numberofhandlesinthehandlearray CONST HANDLE*lpH
15、andles,/pointertotheobject-handlearray BOOL fWaitAll,/waitflag DWORD dwMilliseconds/time-outintervalinmilliseconds);#defineNUM_THREADS10#include#include#includetypedefstructintId;HANDLEhTerminate;ThreadArgs;unsigned_stdcallThreadFunc(void*pArgs)HANDLEhTerminate=(ThreadArgs*)pArgs)-hTerminate;intid=(
16、ThreadArgs*)pArgs)-Id;/运行到被告知终止时while(1)/检查是否需要终止if(WaitForSingleObject(hTerminate,0)=WAIT_OBJECT_0)/终止线程(ResetEvent),终止的线程返回到非激发状态,之后退出while循环printf(hTerminateThread%dn,id);ResetEvent(hTerminate);break;Sleep(1000);/假设处理工作的时间需要1秒_endthreadex(0);return0;案例:使用Windows事件进行线程通信intmain(intargc,char*argv)u
17、nsignedintthreadIDNUM_THREADS;HANDLEhThreadNUM_THREADS;ThreadArgsthreadArgsNUM_THREADS;/创建10个线程for(inti=0;iNUM_THREADS;i+)threadArgsi.Id=i;threadArgsi.hTerminate=CreatEvent(NULL,TRUE,FALSE,NULL);hThreadi=(HANDLE)_beginthreadex(NULL,&ThreadFunc,&ThreadArgsi,0,&threadIDi);printf(Tokillathread,press0-9
18、,then.n);printf(Pressanyotherkeytoexit.n);while(1)intc=getc(stdin);if(c=n)continue;if(c9)break;SetEvent(threadArgsc-0.hTerminate);return0;线程同步多线程应用程序设计的挑战:要保证一个混乱无序和不可预测的真实运行时环境下,线程可以以一种清晰有序的方式执行,从而避免出现例如死锁或竞争导致的数据冲突等难以解决的情况。Win32API中的同步对象:事件、信号量、互斥量以及临界段。基本概念回顾:临界段:在某段时间内仅允许一定数目的线程访问的一段代码。一般情况下,任意时
19、刻下仅允许一个线程进入临界段执行。信号量:一个可以限制对指定临界段进行访问的线程数目的数据结构。互斥量:特殊的信号量,对临界段的互斥访问权仅赋予一个线程。信号量的创建方法HANDLECreateSemaphore(LPSECURITY_ATTRIBUTESlpSemaphoreAttributes,LONGlInitialCout,LONGlMaximumCountLPCTSTRlpName);HANDLEOpenSemaphore(DWORDdwDesiredAccess,BOOLbInheritHandle,LPCTSTRlpName);打开打开创建创建使用信号量对象来保护临界段代码#in
20、clude#ifdef _OPENMPomp_set_num_threads(4);#endifHANDLE hSemaphore;DWORD status;hSemaphore=CreatSemaphore(NULL,1,1,NULL);if(NULL=hSemaphore)/错误处理错误处理.status=WaitForSingleObject(hSemaphore,0);if(status!=WAIT_OBJECT_0)/不能进入临界段:需要恰当进行处理不能进入临界段:需要恰当进行处理else/进入临界段进入临界段/该退出临界段了该退出临界段了status=ReleaseSemaphor
21、e(hSemaphore,1,NULL);if(!status)/释放失败,修复错误释放失败,修复错误互斥量的使用(Mutex:mutualexecution)创建互斥量CreateMutex();调用互斥量WaitForSingleObject();/实现对临界段的访问控制打开一个互斥量:OpenMutex();离开临界段:ReleaseMutex();互斥量的使用流程创建和初始化互斥量;几个线程都试图去锁(lock)该互斥量;只有一个线程获得成功,然后该线程拥有了该互斥量;拥有互斥量的线程开始工作;拥有互斥量的线程释放该互斥量;另一个线程获得互斥量,开始工作;重复该过程。最后,互斥量被销毁
22、。举例:使用互斥量对象来保护临界段HANDLE hMutex;DWORD status;hMutex=CreateMutex(NULL,FALSE,NULL);if(NULL=hMutex)/mutex无效,处理错误无效,处理错误.status=WaitForSingleObject(hMutex,0);if(status!=WAIT_OBJECT_0)/不能进入临界段,需要正确处理不能进入临界段,需要正确处理else/进入临界段进入临界段,进行处理工作进行处理工作./退出退出CSstatus=ReleaseMutex(hMutex);if(!status)/释放失败,进行修复释放失败,进行修
23、复原子操作由于获取互斥量以及其他锁原语的开销可能非常大,而一些特殊的指令使开发人员快速执行普通的原子操作,而不会带来锁获取所导致的开销。微软提供互锁API来支持这些操作。互锁函数提供了32位和64位变量的原子操作。互锁函数提供里对单链表进行原子操作的支持32位和64位变量的原子操作InterlockedIncrement():递增一个32位变量64位版本:InterlockedIncrement64()InterlockedDecrement():递减一个32位变量64位版本:InterlockedDecrement64()InterlockedExchange():将一个32位的值赋给另一个
24、目标变量64位版本:InterlockedExchange64()交换指针:InterlockedExchangePointer()32位和64位变量的原子操作InterlockedExchangeAdd():相当于C语言中的+=操作。把32位目标变量与一个给定值相加,并将二者的和赋给该目标变量。64位版本:InterlockedExchangeAdd64()InterlockedCompareExchange():将比较数与目标值比较,若结果为真,则更新目标值。64位版本:InterlockedCompareExchange64()交换指针:InterlockedCompareExchang
25、ePointer()单链表的原子访问InitializeSListHead():初始化链表InterlockedPushEntrySList():在链表头部加一个节点InterlockedPopEntrySList():在链表头部删除一个节点InterlockedFlushSList():清除链表中的所有节点。线程池线程池API意义:解决线程创建开销与时间相应用户请求时间的矛盾极大的减少开发人员实现线程池所需完成的代码量当使用多个线程对目标工作进行功能分解是,使用线程驰API使Windows有机会协助进行线程的管理。使用线程池最重要的函数:QueueUserWorkItem()QueueUse
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于多核系统的编程技术 第一节 并行 基于 多核 系统 编程 技术
限制150内