VxWorksSMP多核编程指南.docx

上传人:b****2 文档编号:1428018 上传时间:2023-05-01 格式:DOCX 页数:56 大小:342.57KB
下载 相关 举报
VxWorksSMP多核编程指南.docx_第1页
第1页 / 共56页
VxWorksSMP多核编程指南.docx_第2页
第2页 / 共56页
VxWorksSMP多核编程指南.docx_第3页
第3页 / 共56页
VxWorksSMP多核编程指南.docx_第4页
第4页 / 共56页
VxWorksSMP多核编程指南.docx_第5页
第5页 / 共56页
VxWorksSMP多核编程指南.docx_第6页
第6页 / 共56页
VxWorksSMP多核编程指南.docx_第7页
第7页 / 共56页
VxWorksSMP多核编程指南.docx_第8页
第8页 / 共56页
VxWorksSMP多核编程指南.docx_第9页
第9页 / 共56页
VxWorksSMP多核编程指南.docx_第10页
第10页 / 共56页
VxWorksSMP多核编程指南.docx_第11页
第11页 / 共56页
VxWorksSMP多核编程指南.docx_第12页
第12页 / 共56页
VxWorksSMP多核编程指南.docx_第13页
第13页 / 共56页
VxWorksSMP多核编程指南.docx_第14页
第14页 / 共56页
VxWorksSMP多核编程指南.docx_第15页
第15页 / 共56页
VxWorksSMP多核编程指南.docx_第16页
第16页 / 共56页
VxWorksSMP多核编程指南.docx_第17页
第17页 / 共56页
VxWorksSMP多核编程指南.docx_第18页
第18页 / 共56页
VxWorksSMP多核编程指南.docx_第19页
第19页 / 共56页
VxWorksSMP多核编程指南.docx_第20页
第20页 / 共56页
亲,该文档总共56页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

VxWorksSMP多核编程指南.docx

《VxWorksSMP多核编程指南.docx》由会员分享,可在线阅读,更多相关《VxWorksSMP多核编程指南.docx(56页珍藏版)》请在冰点文库上搜索。

VxWorksSMP多核编程指南.docx

VxWorksSMP多核编程指南

VxWorks-SMP多核编程指南

VxWorksSMP多核编程指南

本文摘自vxworks_kernel_programmers_guide_6.8第24章

1.介绍

VxWorksSMP是风河公司为VxWorks设计的symmetricmultiprocessing(SMP)系统。

它与风河公司的uniporcessor(UP)系统一样,具备实时操作系统的特性。

本章节介绍了风河VxWorksSMP系统的特点。

介绍了VxWorksSMP的配置过程、它与UP编程的区别,还有就是如何将UP代码移植为SMP代码。

 

2.关于VxWorksSMP

多核系统指的是一个系统中包含两个或两个以上的处理单元。

SMP是多核技巧中的一个,它的主要特点是一个OS运行在多个处理单元上,并且内存是共享的。

另一种多核技巧是asymmetricmultiprocessing(AMP)系统,即多个处理单元上运行多个OS。

(1)技术特点

关于CPU与处理器的概念在很多计算机相关书籍里有所介绍。

但是,在此我们仍要对这二者在SMP系统中的区别进行详细说明。

CPU:

一个CPU通常使用CPUID、物理CPU索引、逻辑CPU索引进行标示。

一个CPUID通常由系统固件和硬件决定。

物理CPU索引从0开始,系统从CPU0开始启动,随着CPU个数的增加,物理CPU索引也会增加。

逻辑CPU索引指的是OS实例。

例如,UP系统中逻辑CPU的索引永远是0;对于一个4个CPU的SMP系统而言,它的CPU逻辑索引永远是0到3,无论硬件系统中CPU的个数。

处理器(processor):

是一个包含一个CPU或多个CPU的硅晶体单元。

多处理器(multiprocessor):

在一个独立的硬件环境中包含两个以上的处理器。

单核处理器(uniprocessor):

一个包含了一个CPU的硅晶体单元。

例如:

adual-coreMPC8641D指的是一个处理器上有两个CPU;aquad-coreBroadcom1480指的是一个处理器上有四个CPU。

在SMP系统上运行UP代码总会遇到问题,即使将UP代码进行了更新,也很难保证代码很好的利用了SMP系统的特性。

对于在SMP上运行的代码,我们分为两个级别:

SMP-ready:

虽然可以正常的运行在SMP系统上,但是并没有很充分的利用SMP系统的特点,即没有利用到多核处理器的优势;

SMP-optimized:

不仅可以正常的运行在SMP系统上,而且还能很好的利用SMP系统的特点,使用多个CPU使多个任务可以同时执行,提高系统的效率,比UP系统的效果更加明显。

(2)VxWorksSMPOS特点

VxWorks单核编程(UP)与SMP编程在多数情况下是一样的。

类似的,多数API在UP和SMP编程中是通用的。

一些少数UP编程中的API不能在SMP中使用。

与此同时,SMP中的一些API在UP中使用时表现的不是SMP中的效果,而是默认UP的效果,或者压根就不能使用(例如,taskspinlock默认表现为tasklock)。

本小节将简短介绍一下VxWorks的对称多处理器的一些特点:

多任务:

对于传统的UP系统而言,处理多任务的方法是通过任务优先级对CPU资源进行抢占式处理的。

而SMP系统则改变了这种方法,它是实实在在的任务、中断的同时执行。

实现同时执行的关键是多个任务可以在不同的CPU上执行,当然这需要OS的协调控制。

对于UP系统中多任务所谓的同时执行,其实只不过是CPU的快速切换,占有CPU的任务由一个快速切换到另一个。

在SMP系统中,同时执行不是幻想而是实实在在存在的。

任务调度机制:

VxWorksSMP系统中的任务调度机制与UP中的类似,都是基于优先级的。

不同的是,当不同的任务运行在不同的CPU上时,可以实现两个任务的同时执行。

互斥:

由于SMP系统允许任务同时运行的情况存在,因此,在UP系统中通过关中断、锁任务调度等这些保护临界资源的手段在SMP系统中将不再适用。

这种在所有CPU上通过强行关闭中断、锁任务调度的方法会影响到SMP系统发挥它的特点,将SMP系统带回到UP系统的模式。

VxWorksSMP提供一套特殊的任务间、中断间同步/互斥的方法——即UP中的taskLock()和intLock()等将会被VxWorksSMP提供的spinlock,原子操作以及CPU-specific等机制替代。

CPU-Affinity:

默认情况下,任意任务可以运行在任意CPU上。

VxWorksSMP提供了一种叫做CPU-Affinity的机制,即可以分配任务到指定CPU(CPU逻辑索引)上执行。

(3)VxWorksSMP硬件特点

VxWorksSMP系统要求硬件必须具备对称多处理器。

这些处理器必须是一样的,处理器可以共享内存、可以平等的访问所有设备。

VxWorksSMP必须遵循uniformmemoryaccess(UMA)结构。

图1显示了一个双CPU的SMP系统

图1SMP硬件结构

无论SMP系统中CPU的个数是多少,它们的重要特点是一样的:

a.内存对所有CPU可见,不存在“只属于某个CPU的内存”的情况。

即任意CPU可以在任意内存中执行代码;

b.每个CPU都有MemoryManagementUnit(MMU)。

MMU可以使任务在不同的虚拟内存中同时运行。

例如,RTP1的一个任务可以在CPU0上运行,与此同时,RTP2的一个任务可以在CPU1上运行;

c.每个CPU可以访问所有设备。

设备产生的中断可以通过可编程中断控制器发送到任意CPU上执行;

d.通过多CPU,任务和ISR可以实现同步;通过spinlock,任务和ISR可以实现互斥;

e.Snoopbus的作用是使CPU之间的datacache总是保持前后一致性。

(4)VxWorksSMP与AMP的对比

关于SMP与AMP系统中对内存访问的对比如图2所示:

图2SMP系统对内存的占用情况

在SMP系统中,所有物理内存被所有CPU共享。

内存空间可以用来保存VxWorksSMP镜像、Real-TimeProcess(RTP)等。

所有CPU可以读、写、运行所有内存。

内核任务、用户任务可以在任意CPU中执行。

在SMP系统中,所有内存、设备被所有CPU共享,CPU之间的主要通讯是如何防止“同时访问共享资源”的情况发生。

图3AMP系统对内存的占用情况

在AMP系统中,每个CPU对应一个VxWorks镜像的拷贝,它们只能被对应的CPU访问。

因此,CPU1中执行的内核任务不可能在CPU0的内存中执行,反之亦然。

对于RTP也是一样的。

在AMP系统中,一些内存是共享的,但是在这些共享内存中读写数据是严格受到控制的。

例如,在两个VxWorks镜像中传递数据等。

硬件资源根据OS被划分,因此CPU之间的通信只有在访问共享内存时才会发生。

 

3.VxWorksSMP配置说明

Spinlock的调式版本组件

INCLUDE_SPINLOCK_DEBUG提供了spinlock的版本,这对调试SMPAPP有帮助。

在包含INCLUDE_SPINLOCK_DEBUG的同时,最好要加入INCLUDE_EDR_ERRLOG组件,它可以记录spinlock的错误信息。

CPU配置参数组件

INCLUDE_KERNEL组件中包含了一些对VxWorksSMP参数的配置,包括:

VX_SMP_NUM_CPUS代表VxWorksSMP的使能CPU个数。

所有体系结构的最大使能CPU个数如下:

ARM=4,IA32=8,MIPS=32,PowerPC=8,VxWorksSimulator=32。

ENABLE_ALL_CPUS默认是TRUE,代表所有已配置的CPU使能。

这个参数也可以设置为FALSE,一般出于调试目的,此时只有逻辑CPU0是使能的,只有通过kernelCpuEnable()才可以使能指定的CPU。

VX_ENABLE_CPU_TIMEOUT代表CPU使能超时时长,当ENABLE_ALL_CPUS是TRUE时,该值表示所有CPU的使能时长,当ENABLE_ALL_CPUS是FALSE时,在kernelCpuEnable()被调用时,它用来表示CPU的启动时长。

VX_SMP_CPU_EXPLICIT_RESERVE表示将指定CPU排除在“可使用CPU-Affinity属性的CPU池”之外。

它是一个字符串,若填写“237”,则代表CPU2,3,7不能使用CPU-Affinity属性。

即不能通过taskCpuAffinitySet()分配任务到这些CPU上运行。

当某个CPU被VX_SMP_CPU_EXPLICIT_RESERVE包含,唯一能够使他们恢复预留属性的方法是调用vxCpuReserve()。

 

4.在多核AMP系统上配置VxWorksSMP

 

5.启动VxWorksSMP

在WorkBench开启后会有一个默认的SMP的simulator,如图4所示:

图4WR自带的SMP虚拟机

点击连接后启动,启动过程如图5所示,代表目前已经进入VxWorksSMP系统以及当前CPU的个数。

图5SMP虚拟机启动过程

启动后在SHELL中输入i可以查看系统目前运行的任务,你会发现两个idle任务,它们分别运行在两个不同的CPU上。

如图6所示。

图6SMP系统任务运行情况

 

6.VxWorksSMP编程

VxWorks单核编程(UP)与SMP编程在多数情况下是一样的。

类似的,多数API在UP和SMP编程中是通用的。

一些少数UP编程中的API不能在SMP中使用。

与此同时,SMP中的一些API在UP中使用时表现的不是SMP中的效果,而是默认UP的效果,或者压根就不能使用(例如,taskspinlock默认表现为tasklock)。

由于SMP系统的特殊性,因此SMP编程需要特别注意,尤其是在互斥/同步机制上,在使用的时候需要充分考虑如何提高系统的性能。

在VxWorksSMP系统中针对每个CPU都有一个idle任务,这在UP中是没有的。

Idle任务是最低优先级(用户级任务是不能达到这么低优先级的)。

当CPU进出idle状态时,idle任务会提供任务上下文,这可以用来监视CPU的利用率情况。

当CPU无事可做时,Idle任务的存在不会影响CPU进入睡眠状态(当电源管理开启时)。

可以使用kernelIsCpuIdle()或者kernelIsSystemIdle()这两个API查看一个指定CPU是否执行了idle任务或者所有CPU是否执行了idle任务。

【注意】不要对idle任务进行挂起、关闭、跟踪、改变优先级等一系列操作。

SMP的互斥/同步机制

SMP编程与UP编程最大的一个不同就是互斥/同步API的使用。

有一些API在这两种编程中都可以使用,而有一些则不同。

此外,UP编程中的一些隐式同步技巧(例如使用任务优先级替代显示同步锁等)在SMP中是不能用的。

与UP系统不同,SMP系统允许真正意义上的同时执行。

即多个任务或多个中断可以同时执行。

在绝大多数情况下,UP系统中与SMP系统中的互斥/同步机制(例如,信号量、消息队列等)是一样的。

但是,UP中的一些机制(例如,关中断、挂起任务抢占机制以此来保护临界资源等)在SMP中是不适用的。

这是因为这些机制阻碍了同时执行的理念,降低了CPU的利用率,是的SMP系统向UP系统的回溯。

SMP编程与UP编程的一点不同是关于taskLock()和intLock()的使用上。

SMP提供了以下互斥/同步锁机制进行替代:

a.任务级、中断级的spinlock;

b.任务级、中断级的CPU-specific;

c.原子操作;

d.内存障碍(memorybarrier)

 

7.spinlock互斥/同步机制

在UP(单核)编程中通过信号量的方法可以实现task的互斥与同步,在SMP系统中可以继续沿用信号量的机制,而spinlock则用于替换UP编程中使用taskLock()和intLock()的地方。

简介taskLock()和intLock()

通过taskLock()可以关闭系统的任务调度机制,调用taskLock()的任务将是唯一获得CPU运行资源的任务,直到这个任务调用taskUnlock()为止。

intLock()与taskLock()类似,intLock()用于关闭中断,使得中断IRS无法执行,直到调用者调用了intUnlock()。

Spinlock具有“满内存障碍”属性

VxWorksspinlock的获取与释放操作具备“满内存障碍”属性。

“满内存障碍”属性可以使读、写内存操作按照严格的顺序执行而不受到多CPU的影响。

因此,在申请与释放spinlock之间进行更新的数据可以保证“更新顺序”。

Spinlock的种类

Spinlock分为两种:

中断级spinlock和任务级spinlock:

a.中断级spinlock:

可用于关闭本地CPU的中断。

当任务调用中断级spinlock时,将会关闭本CPU的任务抢占机制;

b.任务级spinlock:

用于关闭本地CPU的任务抢占机制。

(本第CPU指的是调用这些API的CPU)

Spinlock的作用以及使用说明

与信号量不同的是,当一个任务试图申请一个已被另一个任务占用的spinlock时,该任务并不会进入阻塞状态(pend),而是可以继续运行,它会进入一个简单的、紧凑的循环直到spinlock得到释放。

这种等待spinlock释放的状态可以用’spinning’和’busywaiting’来描述。

在此,我们可以看出spinlock的优点和缺点。

优点是:

由于任务(或ISR)在等待spinlock的时候没有进入pend状态而是继续执行(一个简单的循环用于获取spinlock),这就避免了任务调用度以及上下文切换的消耗。

缺点是:

循环操作没有实际意义,会占用CPU资源。

因此,只有在必要时才使用spinlock。

即占用spinlock的时间越短,spinlock的优势发挥的越明显(例如UP中的taskLock()和intLock())。

否则,如果占用spinlock较长的时间,在UP编程中的缺陷(增加了任务和中断的响应时间)同样也会在多核编程中出现。

在一个CPU上获取spinlock,并不会影响另一个CPU上任务和中断的调度机制。

当一个任务在持有spinlock的时候,该任务不能被删除。

(1)中断级spinlock

任务和中断都可以获使用中断级spinlock。

有两种中断级spinlock:

确定性的和非确定性的。

【注意】在UP系统中,中断级spinlock与intLock()和intUnlock()的效果是一样的。

确定性中断级spinlock

确定性中断级spinlock的最大特点是:

公平、确定性。

Spinlock会分给第一个申请的中断或任务。

申请的spinlock会屏蔽掉本地CPU的其他中断。

如果是一个任务申请了中断用spinlock,本地CPU的任务调度机制将被停止直到该任务释放spinlock。

Spinlock确保了任务可以独占CPU完成一些操作。

其他CPU上的中断和任务不会受到干扰。

确定性中断级spinlock的API全部包含在spinLockLib中,API如表1所示。

表1确定性中断级spinlock的API

API

描述

voidspinLockIsrInit(

spinlockIsr_t*pLock,/*pointertoISR-callablespinlock*/

intflags/*spinlockattributes*/

初始化确定性中断级spinlock

voidspinLockIsrTake(

spinlockIsr_t*pLock/*pointertoISR-callablespinlock*/

获取确定性中断级spinlock

voidspinLockIsrGive(

spinlockIsr_t*pLock/*pointertoISR-callablespinlock*/

释放确定性中断级spinlock

非确定性中断级spinlock

非确定性中断级spinlock提供了更高的性能,但是当多个CPU试图同时申请一个spinlock时,它并不保证公平性和确定性。

即非确定性中断级spinlock并不一定会把spinlock分配给第一个申请者。

它的优势在于中断响应时间较短,即当CPU等待获取spinlock的时候,中断不会被屏蔽。

API如表2所示。

表2非确定性中断级spinlock的API

API

描述

voidspinLockIsrNdInit(

spinlockIsrNd_t*spin/*pointertospinlock*/

初始化非确定性中断级spinlock

intspinLockIsrNdTake(

spinlockIsrNd_t*spin/*pointertospinlock*/

获取非确定性中断级spinlock

voidspinLockIsrNdGive(

spinlockIsrNd_t*spin,

intkey/*returnvalueofspinLockIsrNdTake*/

释放非确定性中断级spinlock

(2)任务级spinlock

任务级spinlock(中断不可调用该spinlock)可以关掉本地CPU的任务切换机制,使持有spinlock的任务独占CPU完成一些操作。

同时,它不会对其他CPU上的任务调度机制产生影响。

【注意】SMP中任务级spinlock等同于UP编程中的taskLock()和taskUnlock()

API如表3所示。

表3任务级spinlock的API

API

描述

voidspinLockTaskInit(

spinlockTask_t*pLock,/*pointertotask-onlyspinlock*/

intflags/*spinlockattributes*/

初始化任务级spinlock

voidspinLockTaskTake(

spinlockTask_t*pLock/*pointertotask-onlyspinlock*/

获取任务级spinlock

voidspinLockTaskGive(

spinlockTask_t*pLock/*pointertotask-onlyspinlock*/

释放任务级spinlock

(3)Spinlock的使用注意事项

由于SMP系统允许任务的同时运行,因此在使用spinlock的时候需要注意以下事宜:

a.spinlock最好用于短时间占用的情况;

b.任务(或中断)一次只能申请一个spinlock。

当一个已申请了spinlock的实体再一次申请了另一个spinlock时,很有可能会造成死锁;

c.任务(或中断)不能申请它已经持有的spinlock。

这可能会造成死锁;

d.持有spinlock的任务(或中断)不能再调用一些特殊函数(尤其是内核函数),由于这些特殊函数本身持有spinlock,这种操作可能会导致死锁。

(4)Spinlock的调式版本

Spinlock的调试版本可以运行那些开发中使用了spinlock的程序对spinlock的情况进行调试。

这需要添加INCLUDE_SPINLOCK_DEBUG组件。

如果添加了INCLUDE_EDR_ERRLOG组件,则当由使用spinlock造成的系统异常进而重启后,相关信息会被记录下来。

会产生错误信息的情况如表4所示。

表4使用spinlock会出现错误的情况

使用的API

错误信息

spinLockTaskTake()

一个中断任务使用了该API

申请了已持有的spinlock

嵌套申请spinlock

spinLockTaskGive()

一个中断任务使用了该API

试图释放一个没有申请过的spinlock

spinLockIsrTake()

申请了已持有的spinlock

嵌套申请spinlock

spinLockIsrGive()

试图释放一个没有申请过的spinlock

(5)Spinlock中限制使用的系统API

当任务(或中断)持有spinlock时,一些系统API不能被调用(具体原因见Spinlock的使用注意事项)。

这样做为的是防止持有spinlock的任务或ISR进入内核临界区,这可能会导致死锁的发生。

这种限制对于intCpuLock()也是适用的。

这是因为有些内核API需要中断操作。

这些限制看起来好像使spinlock的运用受到影响,但是它们却是有必要的。

Spinlock适用于进程间很快的同步/互斥情况。

若将spinlock用在会进行大量操作——包括内核API调用等——的情况时,则会导致SMP性能的下降。

这是因为当使用spinlock时,任务抢占机制以及中断都将会被关闭。

图7列出了在使用spinlock和CPUlock时限制使用的系统API。

图7spinlock中限制使用的系统API

 

8.CPU-specific互斥机制

VxWorksSMP提供了一种基于CPU-specific的互斥机制,它可以严格限定互斥操作的范围在调用该操作的CPU(本地CPU)上执行。

通过设计CPU-specific使得将UP代码转到SMP系统上变得容易。

(1)中断级CPU-specific

中断级CPU-specific可以关闭本地CPU上的中断。

例如,当任务A在CPU-0上运行一个本地CPU的中断锁操作,则该CPU将不再允许其他中断执行,直到任务A释放这个锁。

SMP系统中其他的CPU将不会受到影响。

对于那些想要使用CPU-specific互斥机制的任务和ISR,必须使用CPU-Affinity将它们指定运行在本地CPU上,只有这样CPU-specific互斥才会有意义。

与spinlock一样,在执行中断锁的任务中有些系统API不能被使用(详见图7)。

中断级CPU-specific的API如表5所示。

【注意】在UP中,它们默认的操作与intLock()和intUnlock()一样。

表5中断级CPU-specific互斥API

API

描述

intintCpuLock(void);

当CPU-0上的任务或ISR调用了该函数后,则禁止在CPU-0上的一切中断调用。

voidintCpuUnlock(

intlockKey/*lock-outkeyreturnedbyprecedingintCpuLock()*/

恢复在CPU-0上的中断调用。

(2)任务级CPU-specific

任务级CPU-specific可以关闭调用该API的CPU上的任务抢占机制。

例如,当运行在CPU-0上的任务A调用了任务锁操作,则该CPU上将禁止任务切换,即该CPU上其他任务将不能得到运行,直到任务A释放了这个锁或执行了一个阻塞操作。

【注意】调用该操作的任务是不能被移交到另外的CPU上运行的,直到这个锁被释放。

SMP系统中其他的CPU将不会受到影响。

对于那些想

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2