1 概述

  CPU亲和性(affinity)就是进程要在某个给定的CPU上尽量长时间地运行而不被迁移到其他处理器的倾向性。SylixOS支持对称多处理器(Symmetric Multi-Processor),其线程是调度的最小单位,SylixOS可以对应用层线程,内核线程以及中断设置CPU亲和性,即将不同线程绑定到不同CPU,充分发挥多核处理器并行处理的优势。

2 SylixOS设置CPU亲和性

  SylixOS中每个线程都有一个对应的线程控制块,线程控制块中与CPU亲和性最高的是CPU位掩码,这个位掩码由 n 位组成,与系统中的 n 个逻辑处理器一一对应。 具有 4 个物理 CPU 的系统可以有 4 位。如果这些 CPU 都启用了超线程,那么这个系统就有一个 8 位的位掩码。

  如果为给定的进程设置了给定的位,那么这个进程就可以在相关的 CPU 上运行。因此,如果一个进程可以在任何 CPU 上运行,并且能够根据需要在处理器之间进行迁移,那么位掩码就全是 1。这也是SylixOS线程中CPU亲和性的默认状态。

2.1 线程与CPU绑定

  SylixOS兼容POSIX标准,应用层线程和内核线程的CPU亲和性设置可以使用POSIX接口。pthread_setaffinity_np函数的第三个参数即为CPU掩码。如程序清单2-1所示。

程序清单2-1  线程与CPU绑定

int pthread_setaffinity_np (pthread_t  thread, size_t setsize, const cpu_set_t *set)

函数名称: pthread_setaffinity_np

功能描述: 设置线程调度的 CPU 集合

输 入  : pid           进程 / 线程 ID

         setsize       CPU 集合大小

         set           CPU 集合

输 出  : ERROR or OK

2.2 中断与CPU绑定

   SylixOS中断源的CPU亲和性设置与线程的CPU亲和性设置函数接口相似,如程序清单2-2所示。

程序清单2-2  中断与CPU绑定

ULONG API_InterSetTarget (ULONG  ulVector, size_t  stSize, const PLW_CLASS_CPUSET  pcpuset)

函数名称: API_InterSetTarget

功能描述: 设置指定中断向量目标 CPU

输 入  : ulVector      中断向量号

         stSize        CPU 掩码集内存大小

         pcpuset       CPU 掩码

输 出  : ERROR CODE

3 示例

  示例环境:ZYNQ7000 双核。

3.1 绑定程序示例

  1.SylixOS在/proc/kernel/affinity文件中记录了CPU亲和性信息,如图3-1所示,可以看到除空闲任务绑定到对应CPU上,别的任务CPU亲和性标记为*表示任务可以在所有CPU上运行。


图3-1  运行测试程序前CPU亲和性信息

  2.运行如程序清单3-1所示测试程序,将主线程绑定到CPU1,子线程绑定到CPU0。

程序清单3-1  CPU绑定测试程序

#include <stdio.h>

#include <pthread.h>


void* task (void* arg) {

    while(1) {

        printf("Hello SylixOS!\n");

        sleep(1);

    }

 

    return NULL;

}

int main (int argc, char **argv)

{

    pthread_t         tid;

    pthread_attr_t    attr;

    cpu_set_t         cpuset;

    
    pthread_attr_init(&attr);

    pthread_create(&tid, &attr, task, NULL);
    
    
    /*

     * 主线程绑定到CPU1

     */

    CPU_ZERO(&cpuset);

    CPU_SET(1, &cpuset);

    pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
    
    /*

     * 子线程绑定到CPU0

     */

    CPU_ZERO(&cpuset);

    CPU_SET(0, &cpuset);

    pthread_setaffinity_np(tid, sizeof(cpu_set_t), &cpuset);
    
    while(1) {

        sleep(5);

    }
 
    pthread_join(tid, NULL);
 
    return  (0);

}

  3. 再查看/proc/kernel/affinity文件中的CPU亲和性信息,如图3-2所示,可以看到执行测试程序后,主线程绑到到CPU1,子线程绑定到CPU0。


图3-2  运行测试程序后CPU亲和性信息

  4.输入ts命令查看线程信息,如图3-3所示,可以看到主线程确实在CPU1上运行,子线程在CPU0上运行,符合测试程序结果。


图3-3  ts命令查看线程信息

3.2 绑定程序示例

  SylixOS提供ints命令可以查看中断向量的信息,如图3-4所示,红框标记的数值为系统启动后对应中断在对应CPU的中断响应次数。


图3-4  中断向量信息

  将部分中断与CPU1绑定后,再执行ints命令,如图3-5所示,可以看到后续的中断响应次数仅在CPU1上累加,CPU0上数值不变表明中断不再由CPU0处理。


图 3-5  中断绑定到CPU1后的中断向量信息

  注意:时钟中断的CPU亲和性由硬件决定,不能将其绑定到CPU1。

4 参考资料

  《SylixOS应用开发手册》

  《管理处理器的亲和性》   https://www.ibm.com/developerworks/cn/linux/l-affinity.html