第一范文网 - 专业文章范例文档资料分享平台

VxWorks SMP多核编程指南 (6)

来源:用户分享 时间:2020-06-23 本文由沿途的风景 分享 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:xxxxxx或QQ:xxxxxx 处理(尽可能给您提供完整文档),感谢您的支持与谅解。

13. CPU信息及管理

VxWorks SMP提供了一些API和宏定义用于获取及操作CPU的信息。 (1) CPU的信息及管理API

kernelLib和vxCpuLib库提供了用于获取CPU信息以及管理CPU的相关API。kernelLib中的CPU API如表10所示。

表 10 CPU内核信息API

API 描述 BOOL kernelIsCpuIdle( 查看指定CPU是否为空闲状态。返回TRUE unsigned int cpu /* CPU to query status 表示CPU为空闲状态。 of */ ) BOOL kernelIsSystemIdle (void) 查看所有可用CPU是否为空闲状态。返回TRUE表示为空闲状态。 STATUS kernelCpuEnable ( 通过输入index参数使能CPU unsigned int cpuToEnable /* logical index of CPU to enable */ ) kernelCpuEnable()可以通过输入index参数来使能指定的CPU。一旦CPU使能,任务调度机制开始在该CPU上分配任务。所有CPU在默认情况下是使能状态,可以将组件ENABLE_ALL_CPUS设置为FALSE,这样VxWorks SMP系统启动后只有CPU 0为使能状态。然后,再通过kernelCpuEnable()可以使能指定的CPU。

vxCpuLib中的CPU API如表11所示。

表 11 CPU信息API

API unsigned int vxCpuConfiguredGet (void) cpuset_t vxCpuEnabledGet (void) unsigned int vxCpuIndexGet (void) cpuid_t vxCpuIdGet (void) 描述 返回在SMP系统中已配置的CPU个数 返回使能CPU的个数 返回当前CPU的索引(逻辑编号) 返回当前CPU的ID(有体系结构变量定义的,非OS定义的逻辑编号) 使用vxCpuConfiguredGet()返回的是配置在BSP中的VxWorks SMP系统的CPU个数。这个值可能与硬件实际存在的CPU个数不一致。

使用vxCpuEnabledGet()返回的是系统中运行CPU的个数。这个值可能与vxCpuConfiguredGet()返回的值不一致,也可能与硬件中实际存在的CPU个数不一致

vxCpuEnabledGet()的返回值类型为cpuset_t,因此我们需要注意:再给返回值赋值之前,我们必须使用CPUSET_ZERO()将cpuset_t变量清0.

vxCpuIndexGet()返回的是当前调用任务使用的CPU索引(逻辑编号)。该编号在0和N-1之间(N是vxCpuConfiguredGet()的返回值)。需要注意的是:默认情况下,任务可以从一个CPU跑到另一个CPU上执行,所以不能保证任务结束后所在的CPU索引与刚才使用vxCpuIndexGet()返回的值是一致的。除非该任务是分配运行在指定CPU上的,或者使用了taskCpuLock()或者intCpuLock()。

(2) CPU相关变量以及宏定义

VxWorks SMP提供了一组变量和宏定义,通过设置这些值可以对CPU的配置进行控制。 例如cpuset_t,它用于标识配置在VxWorks SMP系统中的CPU。Cpuset_t的位值标识了CPU的逻辑索引,Cpuset_t的第一位标识了CPU0,第二位标识了CPU1,第三位标识了CPU2,以此类推(它与CPU在硬件中的物理位置无关)。

例如,有8个CPU的硬件系统,在BSP中为VxWorks SMP配置了4块CPU,通过CPUSET_ZERO()可以讲cpuset_t中的位值清0。调用vxCpuIndexGet(),它的返回值只会设置前四位。

CPU宏定义用于设置和清除CPU索引(通过改变cpuset_t的值)。这些宏定义如图12所示。

表 12 操控CPU信息的宏定义

API CPUSET_SET(cpuset, n) CPUSET_SETALL(cpuset) CPUSET_SETALL_BUT_SELF(cpuset) CPUSET_CLR(cpuset, n) CPUSET_ZERO(cpuset) CPUSET_ISSET(cpuset, n) CPUSET_ISZERO(cpuset) CPUSET_ATOMICSET(cpuset, n) CPUSET_ATOMICCLR(cpuset, n) 描述 设置CPU的索引(只针对一个CPU进行设置) 设置CPU的索引(针对所有CPU进行设置) 设置CPU的索引(除了调用该宏的CPU之外的所有CPU) 清除一个指定的CPU索引(只针对一个CPU进行设置) 清除所有CPU索引(针对所有CPU进行设置) 当指定索引存在于cpuset_t中时,返回TRUE, 当cpuset_t中没有索引时,返回TRUE, 原子地设置CPU的索引(只针对一个CPU进行设置) 原子地清除CPU的索引(只针对一个CPU进行设置) 【注意】不要直接对cpuset_t进行操作,而是要通过上面的宏定义间接的对cpuset_t进行操作。

14. 查看任务性能API

通过checkStack()可以查看所有任务栈的使用情况。在shell下输入checkStack就可以得到下面的信息。如图8所示。

图 8 通过checkStack检测任务栈情况

SIZE表示任务栈的大小,CUR表示当前使用任务栈的大小,HIGH表示使用任务栈的峰值,MARGIN表示从没有使用过的任务栈大小(其中MARGIN = SIZE - HIGH)。

通过spy()可以上报任务在内核空间、中断、idle中的tick使用情况。在shell下输入spy就可以得到下面的信息。如图9所示。

图 9 通过spy查看CPU使用率情况

Spy开启了tSpyTask用于监控系统任务的使用情况。IDLE表示空闲任务的CPU占用情况。

15. SMP性能优化

SMP的目的就是提高系统的性能。如果仅仅是简单的使用SMP的代码,并不能完全发挥出SMP的潜能。因此,在SMP代码的基础上还需要进行优化。

SMP算法是否能够提高系统性能很大程度上取决于算法并行性的程度以及多线程独立的程度。有些算法是高可并行性的,并且很好的利用了多CPU。一个很好的例子:图形压缩器可以在独立的线程中分别压缩一整块数据中的一小块。

如果SMP算法不好的话,那么同时执行两个线程的消耗将会抵消掉多个CPU所带来的

好处。类似的,如果存在很多共享数据,即多个CPU需要争夺的数据,那么系统将会增大争夺、等待数据的消耗。

不好的算法会导致更糟糕的情况,即SMP系统反而不如UP系统运行的快。最好的情况是使运算速度提高一倍。 线程化

线程化包括将一个单线程的APP通过任务复制的方式变成多线程。一个典型的例子是:唤醒一个“工人”任务,这个任务的工作是从一个队列中获取工作,还有一个任务或ISR负责往这个队列中填充工作。假设瓶颈出现在“工人”任务中,我们可以通过复制“工人”任务的方式提高系统的性能。线程化不是一个新的概念了,在出现多线程OS的时候我们就已经知道这个词了。但是在一个UP系统中,线程化只能增加任务的吞吐量,即虽然线程增加了,但它们却在等待资源。到头来我们发现瓶颈是在CPU本身,而线程化并不能提高性能。例如,在一个UP系统上计算密集的APP,线程化不能帮上什么忙。但是在SMP系统上情况有所不同,线程化可以有效地提高系统性能,这是因为SMP系统解决了CPU的瓶颈问题。

使用Spinlock

使用spinlock会潜移默化的影响中断和任务抢占机制。因此必须谨慎的使用spinlock,使用的话也必须是在很短的周期内使用和释放。

使用浮点数和其他协处理器

出于效率的考虑,关于使用协处理器的任务创建选项(VP_FP_TASK)必须被谨慎使用。只有当任务确实需要使用时再添加。当一个任务在创建时开启了协处理器选项时,协处理器的状态将被保存,同时,系统也会保存每一次的上下文切换。这对于那些虽然开启了协处理器但是却没有使用它的任务而言显得没有必要了。

使用vmBaseLib

vmBaseLib库是VxWorks MMU的管理库,它允许内核APP和驱动管理MMU。SMP OS的一个重要任务是保证MMU的后备内存(TLB)的一致性。例如,CPU MPC8641D中有硬件资源可以保证TLB的一致性。其他CPU,例如MIPS体系结构家族,就没有这个能力。这时候就需要OS进行对MMU一致性的保护了。

任务和中断的CPU-Affinity

对于一些APP和系统,分配指定任务或中断到指定CPU上执行可以提高系统的效率。

16. 简单例子

VxWorks SMP提供了一些测试程序,用来测试SMP的特点和性能。以下程序测试了I/O

功能和系统调用功能: philDemo

smpLockDemo

以下测试了计算能力: primesDemo rawPerf

可以通过配置VxWorks内核的方式(添加INCLUDE_SMP_DEMO组件),将这些测试程序链接到VxWorks SMP内核镜像中。测试源代码在installDir/vxworks-6.x/target/src/demo/smp中。

在此以installDir/vxworks-6.x/target/src/demo/smp/smpLockDemo.c为例来说明关于SMP编程的一些注意事项:

/ * smpLockDemo.c用于测试VxWorks SMP的同步/互斥机制 * 描述:

* 这个demo描述了VxWorks SMP中的同步机制。在SMP系统中任务和ISR可以同时运* 行在不同的CPU上,这就涉及到同时访问共享数据的问题,对此,VxWorks SMP提供 * 了一系列机制:

* 信号量(Semaphore):可以使用信号量实现任务间的同步机制。例如,使用一个任务或* ISR“唤醒”另一个任务。

* VxWorks事件(VxWorks Events):同信号量。 * 原子操作(Atomic Operator):能够安全的读、写内存。例如,完成一些类型的全局的 * 自增操作。

* Spinlock:它可以用在任务间、ISR间、任务与ISR间的同步。它一般用来对较多的共 * 享数据和临界资源进行保护。 *

* 本demo对以上同步机制进行了对比。通过SMP系统中多个任务对一个共享int型变量 * 操作的实例,来对比这些同步机制。 *

* DEMO执行

* 本demo中包含了两个优先级一样的任务,每个任务都重复地(循环)增加一个共享计 * 数器。这个共享计数器是用户定义的一个累加值(即被更新次数)。每个任务还有一个 * 自己的计数器,在增加共享计数器的同时也增加自己的计数器。假设任务自己的计数器 * 不会出错,我们要看看使用不同同步机制的不同效果,即共享数据的值是否与两个任务 * 自身计数器的值之和一致。 *

* 以上过程重复5次,每次使用不同的同步机制:

* 1. 不使用同步机制:任务访问共享数据时不使用同步机制。

* 2. Spinlock:当任务累加共享数据的时候申请spinlock,然后再释放spinlock。

* 3. vxAtomicInc()原子操作:任务使用原子操作vxAtomicInc()对这个共享数据进行累加。 * 4. vxTas()原子操作:在任务中通过vxTas()设置/清除一个flag,将这个flag当做一个普 * 通信号量使用。当这个flag被清除时表示信号量不可用,当被设置时表示可用。任务 * 需要使用这个信号量对共享数据进行累加,然后再释放信号量。

* 5. vxAtomicAdd()原子操作:在任务中使用vxAtomicAdd()原子操作对共享数据进行累 * 加。 *

搜索“diyifanwen.net”或“第一范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,第一范文网,提供最新高中教育VxWorks SMP多核编程指南 (6)全文阅读和word下载服务。

VxWorks SMP多核编程指南 (6).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.diyifanwen.net/wenku/1098898.html(转载请注明文章来源)
热门推荐
Copyright © 2018-2022 第一范文网 版权所有 免责声明 | 联系我们
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:xxxxxx 邮箱:xxxxxx@qq.com
渝ICP备2023013149号
Top