实时调度类及SMP和NUMA

实时调度类及SMP和NUMA

实时调度类

1、Linux进程分为两大类:实时进程和普通进程。实时进程与普通进程根本不同之处,如果系统中有一个实时进程且可执行,那么调度器总会选择它,除非有另一个更高优先级实时进程。

SCHER_FIFO:没有时间片,在被调度器选择之后,可以运行任意长时间

SCHED_RR:有时间片,其值在运行时会减少。

2、实时调度实体 sched_rt_entity

表示实时调度实体,包含整个实时调度数据信息。具体内核源码如下:

65200fd3ac560

可以研究一下这个实时类struct rt_rq

3,实时调度类rt_sched_class数据结构

数据结构源码如下。

6523ac004d4be

实时调度类操作核心函数----》插入进程


/*
 * Adding/removing a task to/from a priority array:
 */
 // 更新调度信息,将调度实体插入到相应优先级队列的末尾
static void
enqueue_task_rt(struct rq *rq, struct task_struct *p, int flags)
{
    struct sched_rt_entity *rt_se = &p->rt;

    if (flags & ENQUEUE_WAKEUP)
        rt_se->timeout = 0;

    enqueue_rt_entity(rt_se, flags);

    if (!task_current(rq, p) && p->nr_cpus_allowed > 1)
        enqueue_pushable_task(rq, p);
}

核心函数--》选择进程,实时调度会选择最高优先级的实时进程来运行。

static struct sched_rt_entity *pick_next_rt_entity(struct rq *rq,
                           struct rt_rq *rt_rq)
{
    struct rt_prio_array *array = &rt_rq->active;
    struct sched_rt_entity *next = NULL;
    struct list_head *queue;
    int idx;

    // 第一个找到一个可用的实体
    idx = sched_find_first_bit(array->bitmap);
    BUG_ON(idx >= MAX_RT_PRIO);

    // 从链表组中找到对应的链表
    queue = array->queue + idx;
    next = list_entry(queue->next, struct sched_rt_entity, run_list);

    return next;    // 返回找到运行实体
}

核心函数--》删除进程,从优先队列中删除实时进程,并更新调度信息,然后把这个进程添加到队尾。

// 删除进程
static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int flags)
{
    struct sched_rt_entity *rt_se = &p->rt;

    update_curr_rt(rq); // 更新调度数据信息等等

    // 将rt_se从运行队列中删除,然后添加到队列尾部
    dequeue_rt_entity(rt_se, flags);

    dequeue_pushable_task(rq, p);
}

SMP和NUMA

SMP

对称多处理器结构

1,CMP服务器CPU利用率最好的情况下是2至4个CPU。SMP调度就是将进程安排/迁移到合适的CPU中去,保持各CPU负载均衡的过程。

SMP优势:当前使用的OTLP程序当中,用于方位一个中心数据库,如果采用SMP系统架构,它的效率要比MPP架构要块。

NUMA

非一致内存访问结构,多CPU,每个CPU都有本地内存。为多处理器计算机。NUMA优势:一台服务器内集成多个CPU,是系统具有较高事务处理能力。NUMA架构适合OLTP事务处理环境。

从应用层系统架构,目前商用服务器大体分为三类:SMP、NUMA、MPP。

CPU域初始化

Linux内核对CPU管理是通过bitmap来管理的,并定义了四种状态:possible/present/online/active。

6523b704b6507

THE END