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

VxWorks SMP多核编程指南 (4)

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

atomicVal_t vxAtomicOr( 将两个值进行位或操作 atomic_t * target, /* memory location to OR */ atomicVal_t value /* OR with this value */ ) atomicVal_t vxAtomicXor ( 将两个值进行位异或操作 atomic_t * target, /* memory location to XOR */ atomicVal_t value /* XOR with this value */ ) atomicVal_t vxAtomicAnd ( 将两个值进行位与操作, atomic_t * target, /* memory location to AND */ atomicVal_t value /* AND with this value */ ) atomicVal_t vxAtomicNand ( 将两个值进行位非与操作 atomic_t * target, /* memory location to NAND */ atomicVal_t value /* NAND with this value */ ) atomicVal_t vxAtomicSet ( 将一个值设定为另一个值 atomic_t * target, /* memory location to set */ atomicVal_t value /* set with this value */ ) atomicVal_t vxAtomicClear( atomic_t * target /* location to clear */ ) 将一个值清空 memory BOOL vxCas( 对比或交换内存中的值。 atomic_t * target, /* memory location to compare-and-swap */ atomicVal_t oldValue, /* compare to this value */ atomicVal_t newValue /* swap with this value */ )

11. CPU Affinity

VxWorks SMP提供了CPU Affinity这种机制。通过这种机制可以将中断或者任务分配给指定的CPU执行。

(1) 任务级 CPU Affinity

VxWorks SMP具有将任务分配给指定CPU执行的能力。从另一个角度来说,即将指定CPU预留给指定任务。

SMP的默认操作——任何任务可以运行在任何CPU上——这会根据系统的整体性能而定。但是有些时候将指定任务分配给指定的CPU对系统性能是有帮助的。例如一个CPU上只运行一个单独的任务而不做其他事情,则这块CPU的cache中就只保存了这个任务所需要的数据和代码。这样做节省了任务在CPU之间切换的消耗。

还有个例子就是当多个任务争夺一个spinlock时,如果这些任务运行在不同的CPU上,则会有大量的时间被浪费在等待spinlock上。若将争夺同一个spinlock的任务指定在同一个CPU上运行,则这会给另一块CPU上执行其他程序带来便利。

关于任务级 CPU affinity的使用方法如下:

a. 一个任务可以通过调用taskCpuAffinitySet()设置自己的CPU affinity,也可以设置

其他任务的CPU affinity;

b. 子任务会继承父任务的CPU affinity。一个任务中调用如下API就会自动继承CPU

affinity: taskSpawn(), taskCreate(), taskInit(), taskOpen(), taskInitExcStk()。 任务级 CPU affinity的API如表8所示。

表 8 任务级CPU Affinity的API

API STATUS taskCpuAffinitySet( int tid, /* task ID */ cpuset_t newAffinity /* new affinity set */ ) 描述 分配一个任务在指定CPU上执行。 STATUS taskCpuAffinityGet( 获得指定任务在哪个CPU上执行。 int tid, /* task ID */ cpuset_t* pAffinity /* address to store task's affinity */ ) taskCpuAffinitySet()和taskCpuAffinityGet()都使用cpuset_t结构对CPU信息进行标示。前者用于分配任务到指定CPU;后者获取指定任务的cpu_set_t。

CPUSET_ZERO()宏定义用于将cpuset_t清0(类似FD_ZERO),它必须被最先调用。 CPUSET_SET()宏定义在CPUSET_ZERO()之后使用。

RTP任务与CPU Affinity

默认情况下,RTP任务会继承父任务的CPU Affinity属性。如果父任务没有CPU Affinity属性,则RTP任务也没有CPU Affinity属性。如果父任务有CPU Affinity属性,则RTP任务也继承该CPU Affinity属性并仅运行在对应的CPU上。在使用rtpSpawn()时,RTP_CPU_AFFINITY_NONE选项表示创建RTP时不继承CPU Affinity属性,即使父任务具有CPU Affinity属性。

任务级 CPU Affinity 示例:

以下代码说明了创建一个任务,并将该任务分配给CPU1执行的全过程:【蓝色部分表示调用的关键API】

STATUS affinitySetExample(void) {

cpuset_t affinity; int tid;

/* Create the task but only activate it after setting its affinity */

Tid = taskCreate(“myCpu1Task”, 100, 0, 5000, printf, (int)”myCpu1Task executed on CPU 1 !”, 0, 0, 0, 0, 0, 0, 0, 0, 0);

if (tid = = NULL) return ERROR;

/* Clear the affinity CPU set and set index for CPU 1 */ CPUSET_ZERO(affinity); CPUSET_SET(affinity, 1);

if (taskCpuAffinitySet(tid, affinity) = = ERROR) { taskDelete(tid); return ERROR; }

/* Now let the task run on CPU 1 */ taskActivate(tid);

return OK; }

下面这个例子是一个任务如何删除它的CPU affinity: {

cpuset_t affinity;

CPUSET_ZERO(affinity);

/* passing a tid equal to zero causes an affinity to be set for the calling task */ taskCpuAffinitySet(0, affinity); }

(2) 中断级CPU Affinity

SMP硬件需要可编程中断控制设备。VxWorks SMP利用这些硬件可以分配中断到指定CPU。默认情况下,中断是在VxWorks的CPU 0中触发的。

通过中断级CPU Affinity,可以将中断合理平均的分配到不同CPU上(而不是在一个CPU上存在很多中断)。

运行时刻分配中断到指定CPU是在启动时发生的,当系统启动从BSP中读取中断配置信息的时候。然后,中断控制器收到一条命令,该命令用于指示一条中断运行在指定的CPU

上。

12. 将CPU预留给使用了CPU Affinity的任务(CPU预留机制)

VxWorks SMP提供了一种机制可以将CPU预留给那些已经使用了CPU Affinity的任务。这种机制可以防止其他任务与使用了CPU预留机制的任务抢占CPU资源,因此它提升了系统效率。CPU预留机制的API如表9所示。

表 9 CPU预留机制API

API STATUS vxCpuReservedGet ( cpuset_t *pCpuSet ) 描述 获取可预留CPU的集合 STATUS vxCpuReserve( 预留CPU集合cpus,返回CPU预留的结果 cpuset_t cpus, /* CPUs to be pReservedCpus reserved */ cpuset_t *pReservedCpus /* CPUs reserved */ ) STATUS vxCpuUnreserve( cpuset_t cpus ) 解除某个CPU的预留机制。 默认情况下,当CPU没有使用vxCpuReserve()时,所有CPU都是可以被预留的。可以通过配置VX_SMP_CPU_EXPLICIT_RESERVE参数,将指定CPU排除在CPU预留池之外。只有在CPU池中的CPU才可以被预留。

taskCpuAffinitySet()与vxCpuReserve()没有明确的调用顺序。前者是把任务分配给指定的CPU,这样可以防止该任务运行在其他CPU上。而后者限定了CPU上可以运行哪些任务。可以根据具体情况分先后调用这两者。

【注意】如果一个任务使用了CPU Affinity,则它的子任务将会继承CPU-Affinity属性;如果一个CPU预留给了使用CPU Affinity的任务,则这些任务的子任务将会在这个CPU上运行。

CPU预留与任务级CPU Affinity的示例

以下程序片段展示了如何预留一个CPU以及设置一个任务级CPU affinity在预留CPU上执行的过程:【蓝色部分表示调用的关键API】 void myRtn(void) { cpuset_t cpuset; /* Input argument to vxCpuReserve() */ cpuset_t resCpuSet; /* Return argument from vxCpuReserve() */ /* Passing an empty cpuset as input reserves an arbitrary CPU */ CPUSET_ZERO(cpuset);

if (vxCpuReserve(cpuset, &resCpuSet) = = OK) { /* set affinity for current task */ if (taskCpuAffinitySet(0, resCpuSet) != OK) /* handle error */ } else { /* handle error */ }

}

以下代码片段展示了如何预留一个或多个指定CPU并且为多个任务设置CPU affinity: void myRtn(void) { extern int tids[3]; /* some task Ids */ int cpuIx[] = {1, 2, 4}; /* CPU indices to reserve */ cpuset_t cpuSet; cpuset_t tmpCpuSet; int i; /* Initialize cpuSet with the desired CPU indices */ CPUSET_ZERO(cpuSet); CPUSET_SET(cpuSet, cpuIx[0]);

CPUSET_SET(cpuSet, cpuIx[1]); CPUSET_SET(cpuSet, cpuIx[2]);

/* Reserve the specified CPUs */

if (vxCpuReserve(cpuSet, NULL) = = OK) { for (i = 0; i < 3; ++i) { tmpCpuSet = CPUSET_FIRST_SET(cpuSet); if (taskCpuAffinitySet(tids[i], tmpCpuSet) != OK) /* handle error */ CPUSET_SUB(cpuSet, tmpCpuSet); } } else { /* handle error */ } }

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

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