首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Linux超线程感知的调度算法研究 03

Linux超线程感知的调度算法研究 03

 Linux通过balance_node( )函数进行物理CPU之间的负载均衡。物理CPU间的负载平衡作为rebalance_tick( )函数中的一部分在 load_balance( )之前启动,避免了出现一个物理CPU运行1-1任务,而第二个物理CPU运行0-0任务的情况。balance_node( )函数首先调用 find_
  busiest_node( )找到系统中最繁忙的节点,然后在该节点和当前CPU组成的CPU集合中进行 load_balance( ),把最繁忙的物理CPU中的线程迁移到当前CPU上。之后rebalance_tick( )函数再调用load_balance(工作集为当前的物理CPU中的所有逻辑CPU)进行逻辑CPU之间的负载均衡。
  (3)支持“主动的”负载均衡
  当一个逻辑 CPU 变成空闲时,可能造成一个物理CPU的负载失衡。例如:系统中有两个物理CPU,一个物理CPU上运行一个任务并且刚刚结束,另一个物理CPU上正在运行两个任务,此时出现了一个物理CPU空闲而另一个物理CPU忙的现象。
  Linux中通过active_load_balance( )函数进行主动的负载均衡,active_load_balance( )函数用于在所有的逻辑CPU中查询该CPU的忙闲情况。如果发现由于超线程引起的负载不平衡(一个物理CPU的两个逻辑CPU都空闲,另一个物理CPU的两个逻辑CPU都在运行两个线程),则唤醒一个需要迁移的线程,将它从一个忙的物理CPU迁移到一个空闲的物理CPU上。
  active_load_balance( )通过调用cpu_rq( )函数得到每一个逻辑CPU上的运行队列。如果运行队列上的当前运行线程为idle线程,则说明当前逻辑CPU为空闲;如果发现一个物理CPU两个逻辑CPU都为空闲,而另一个物理CPU中的两个逻辑CPU的运行队列为繁忙的情况,则说明存在超线程引起的负载不均衡。这时当前CPU会唤醒迁移服务线程(migration_thread)来完成负载均衡的线程迁移。
  (4)支持超线程感知的任务挑选
  在超线程处理器中,由于cache资源为两个逻辑处理器共享,因此调度器在选取一个新任务时,必须确保同组的任务尽量共享一个物理CPU,从而减少cache失效的开销,提高系统的性能。而传统的调度器只是简单地为逻辑CPU选取一个任务,没有考虑物理CPU的影响。
  Linux进行线程切换时会调用schedule( )函数进行具体的操作。如果没有找到合适的任务schedule()函数,则会调度idle线程在当前CPU上运行。在超线程环境中Linux调度idle线程运行之前会查询其同属CPU的忙闲状况。如果同属CPU上有等待运行的线程,则会调用一次load_balance( )函数在两个同属CPU之间作一次负载均衡,将等待运行的线程迁移到当前CPU上,保证优先运行同属CPU上的任务。
  (5)支持超线程感知的CPU唤醒
  传统的调度器只知道当前CPU,而不知道同属的逻辑CPU。在超线程环境下,一个逻辑CPU正在执行任务时,其上的一个线程被唤醒了,此时,如果它的同属逻辑CPU是空闲的,则应该在同属逻辑CPU上运行刚刚唤醒的任务。
  Linux通过wake_up_cpu( )函数实现CPU唤醒,在try_o_wakeup、pull_task、move_task_away加入了wake_up_cpu( )函数的相应调用点。wake_up_cpu()首先查询当前CPU是不是空闲的,如果当前CPU为空闲,则调用resched_cpu( )函数启动调度器,将唤醒的线程调度到当前CPU执行;否则查找其同属逻辑CPU。如果同属逻辑CPU是空闲的,则将唤醒的线程调度到同属逻辑CPU上执行;否则比较唤醒的线程和当前CPU上运行的线程的优先级。如果唤醒的线程的优先级高,或者优先级相等但是时间片多,则进行线程切换,在当前CPU上调度执行唤醒的线程。如果上述条件都不满足,最后比较唤醒的线程和当前CPU的同属逻辑CPU上运行的线程的优先级,如果唤醒的线程的优先级高,或者优先级相等但是时间片多,则在同属逻辑CPU上调度执行唤醒的线程。
返回列表