最新linux中针对SMP的调度算法
时间: 2024-04-01 22:36:41 浏览: 32
Linux内核最新版本中,针对SMP(Symmetric Multi-Processing,对称多处理)的调度算法是CFS(Completely Fair Scheduler,完全公平调度器)。CFS是一种基于红黑树的时间片轮转调度算法,它会根据进程的优先级和历史运行时间来计算各个进程的动态优先级,然后按照优先级从高到低的顺序进行调度。CFS算法能够保证各个进程的CPU时间公平分配,而且能够避免进程饥饿,提高系统的整体性能。
相关问题
LinuxCPU调度算法代码
Linux的CPU调度算法实现在内核的调度器中,其中最常用的是CFS(Completely Fair Scheduler)算法。以下是CFS算法的部分代码实现:
```c
/* 定义进程结构体 */
struct task_struct {
/* 进程状态 */
volatile long state;
/* 进程调度策略和优先级 */
volatile unsigned int policy;
volatile unsigned int prio;
/* 进程调度类 */
volatile unsigned int class;
/* 进程调度参数 */
volatile unsigned int rt_priority;
volatile unsigned int normal_prio;
/* 进程时间片 */
unsigned int time_slice;
/* 进程的vruntime */
u64 se.vruntime;
/* 进程的实际执行时间 */
u64 se.sum_exec_runtime;
/* ... */
};
/* CFS算法的调度策略 */
static const struct sched_class fair_sched_class = {
.next = &idle_sched_class,
.enqueue_task = enqueue_task_fair,
.dequeue_task = dequeue_task_fair,
.yield_task = yield_task_fair,
.check_preempt_curr = check_preempt_wakeup,
.pick_next_task = pick_next_task_fair,
.put_prev_task = put_prev_task_fair,
#ifdef CONFIG_SMP
.load_balance = load_balance_fair,
.migration_cost = migration_cost_fair,
#endif
};
/* CFS算法的进程入队函数 */
static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
{
/* 更新进程的vruntime */
update_curr_fair(rq);
/* 将进程插入红黑树中 */
__enqueue_entity(&p->se, &rq->fair_root);
/* 更新进程的调度信息 */
update_cfs_rq_load_avg(cfs_rq_of(&p->se));
update_load_avg(rq);
update_rq_clock(rq);
/* ... */
}
/* CFS算法的进程出队函数 */
static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags)
{
/* 从红黑树中删除进程 */
__dequeue_entity(&p->se);
/* 更新进程的调度信息 */
update_cfs_rq_load_avg(cfs_rq_of(&p->se));
update_load_avg(rq);
update_rq_clock(rq);
/* ... */
}
/* CFS算法的进程调度函数 */
static struct task_struct *pick_next_task_fair(struct rq *rq)
{
/* 获取最小vruntime的进程 */
struct sched_entity *se = pick_next_entity(&rq->fair_root);
/* 获取进程对应的task_struct结构体 */
struct task_struct *p = task_of(se);
/* 更新进程的调度信息 */
update_cfs_rq_load_avg(cfs_rq_of(se));
update_load_avg(rq);
update_rq_clock(rq);
/* ... */
return p;
}
```
以上代码只是CFS算法的部分实现,详细的代码实现可以在内核源码中找到。
Linux操作系统进程调度算法的代码运行
由于Linux操作系统是开源的,因此其进程调度算法的代码可以在其代码库中找到。具体来说,Linux使用完全公平调度算法(CFS)作为其默认的进程调度算法,其代码实现可以在内核源代码中的sched目录中找到。以下是一些示例代码:
1. CFS调度器代码:
/*
* Completely Fair Scheduler
*
* This file contains the code for the Completely Fair Scheduler, a
* process scheduler based on a red-black tree. It implements a
* proportional-share scheduling algorithm with low latency for
* interactive tasks and high throughput for compute-bound tasks.
*
* Copyright (C) 2002-2007 Ingo Molnar <mingo@elte.hu>
* Copyright (C) 2007-2011 Con Kolivas <kernel@kolivas.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
2. 调度策略代码:
/* Define a scheduling class */
static const struct sched_class fair_sched_class = {
.next = &idle_sched_class,
.enqueue_task = enqueue_task_fair,
.dequeue_task = dequeue_task_fair,
.yield_task = yield_task_fair,
.check_preempt_curr = check_preempt_wakeup,
.pick_next_task = pick_next_task_fair,
.put_prev_task = put_prev_task_fair,
#ifdef CONFIG_SMP
.select_task_rq = select_task_rq_fair,
.migrate_task_rq = migrate_task_rq_fair,
.task_waking = task_waking_fair,
.task_woken = task_woken_fair,
#endif
.set_curr_task = set_curr_task_fair,
.task_tick = task_tick_fair,
.task_fork = task_fork_fair,
.task_dead = task_dead_fair,
#ifdef CONFIG_FAIR_GROUP_SCHED
.task_move_group = task_move_group_fair,
#endif
};
3. 调度器初始化代码:
void __init sched_init(void)
{
int i;
/* Initialize the active and expired arrays for CFS */
for_each_possible_cpu(i) {
struct rq *rq = cpu_rq(i);
int j;
/* Initialize the red-black tree for CFS */
for (j = 0; j < MAX_NICE; j++) {
INIT_LIST_HEAD(&rq->cfs_rq[j].tasks);
INIT_LIST_HEAD(&rq->cfs_rq[j].runnable);
rb_init_node(&rq->cfs_rq[j].rb_node);
}
rq->cfs_rq[0].exec_clock = rq_clock(rq);
rq->cfs_rq[1].exec_clock = rq_clock(rq);
rq->cfs_rq[2].exec_clock = rq_clock(rq);
rq->cfs_rq[3].exec_clock = rq_clock(rq);
rq->cfs_rq[4].exec_clock = rq_clock(rq);
rq->cfs_rq[5].exec_clock = rq_clock(rq);
rq->cfs_rq[6].exec_clock = rq_clock(rq);
rq->cfs_rq[7].exec_clock = rq_clock(rq);
rq->cfs_rq[8].exec_clock = rq_clock(rq);
rq->cfs_rq[9].exec_clock = rq_clock(rq);
rq->cfs_rq[10].exec_clock = rq_clock(rq);
rq->cfs_rq[11].exec_clock = rq_clock(rq);
rq->cfs_rq[12].exec_clock = rq_clock(rq);
rq->cfs_rq[13].exec_clock = rq_clock(rq);
rq->cfs_rq[14].exec_clock = rq_clock(rq);
rq->cfs_rq[15].exec_clock = rq_clock(rq);
rq->nr_running = 0;
rq->nr_uninterruptible = 0;
rq->curr = NULL;
INIT_LIST_HEAD(&rq->migration_queue);
INIT_LIST_HEAD(&rq->expired);
INIT_LIST_HEAD(&rq->active);
rq->expired_timestamp = 0;
rq->next_balance = jiffies + HZ;
rq->skip_clock_update = 0;
rq->idle_stamp = rq_clock(rq);
rq->last_moved = jiffies;
spin_lock_init(&rq->lock);
spin_lock_init(&rq->task_lock);
}
/* Initialize the idle class */
init_idle(&init_task);
init_idle(&ksoftirqd_task);
init_idle(&migration_thread);
/* Initialize the fair class */
sched_register_scheduler(&fair_sched_class);
}