实时调度器类 实时调度类有两类进程:
SMP 下面我们简单介绍一下SMP的主要过程:框架周期性调度器在执行完上面所说的过程后会调用trigger_load_balance触发个SCHEDULE_SOFTIRQ软中断,该中断确保会在适当的时机执行run_rebalance_domains。该函数最终对当前CPU调用rebalance_domains判断该CPU下的每个调度域是否需要balance,如果需要最终将调用load_balance来实现负载均衡;另外内核为每个就绪队列提供一个迁移线程,用来接收迁移请求,这些请求被保存在migration_queue链表中。load_balance函数首先查找CPU(进入这个过程的CPU已经是CPU_IDLE)所属调度域内最忙的(CPU)运行队列,然后使用move_tasks将该队列(最忙)中适当数目的进程迁移到当前CPU的运行队列里,最终move_tasks调用特定调度器类的load_balance方法。下面两种进程在load_balance里无法完成: A. 进程由于亲缘性不能在当前CPU下运行 B. 进程正在运行(成本太大) 当load_balance失败的时候(没有完成一个进程的balance),会设置最忙运行队列的active_balance及它将要迁移的目标CPU(当前CPU),然后唤醒最忙CPU的迁移线程wake_up_process(busiest->migration_thread),那么此时最忙CPU运行的就是这个迁移线程(之前的线程不再运行),所以之前的线程现在就有可能会被迁移到目标CPU;最忙CPU运行迁移线程,当它检查到rq->active_balance则调用active_load_balance,最终分别调用特定调度器类的move_one_task函数(该函数完成的过程会比load_balance更激烈的方法,如不考虑优先级)。 调度域:多个就绪队列(CPU)组织为一个调度域,将物理上邻近或共享高速缓存的CPU群集起来,它是负载均衡的单位,在balance时应优先选择在同一个调度域内的CPU之间的迁移 在CPU(逻辑CPU)间的迁移优先(这也关系到调度域的组织):同一个core(L1,L2),同一个物理CPU(L3),同一个NUMA节点。我们的开发机器是2个物理CPU,每个物理CPU内有4个core,每个core又虚拟出2个超线程,所以我们看到的16个CPU,其实是16个超线程,一般的NUMA初始设置是把同一个物理CPU的放在同一个NUMA节点内。这些信息可以从/proc/cpuinfo查看:processor(表示逻辑cpu,也就是超线程);physical id(表示物理CPU ID);core id(表示一个物理CPU内的core id,不同CPU间的core id可能一样);siblings(表示)一个物理CPU上的超线程数;cpu cores(表示一个物理CPU的core数)
|
|