2013-01-09 100 views
4

我想了解負載平衡器如何在Linux內核的多處理器系統上,什麼呢的struct sched_domain代表在在include/linux/sched.h中(在內核調度域)

Linux調度主要採用runques存儲它有下一次運行的任務, 現在採取的多處理器系統 在羅伯特給出load_balancer()的方式實現的解釋的情況下愛書Linux內核開發第二版是繼

首先,LOAD_BALANCE( )調用find_busiest_queue()來確定 最繁忙的runqueue。換句話說,這是其中最大數量的進程的runqueue。如果不存在具有比當前多25%或更多進程的運行隊列,則find_busiest_queue()返回 NULL和load_balance()返回。否則,返回最繁忙的隊列是 。其次,load_balance()決定它想從哪一個最繁忙的運行隊列中取出哪個優先級數組。因爲 這些任務沒有在相對較長的時間內運行,因此大多數 可能不在處理器的緩存中(即它們不是緩存熱點),所以優先使用過期陣列。 如果過期的優先數組是空的,則活動的數組是唯一的選擇 。

接下來,load_balance()查找具有任務的最高優先級(最小值)列表 ,因爲公平分配高優先級任務比低優先級任務更重要。

分析給定優先級的每個任務,找到一個任務,即 未運行,未阻止通過處理器關聯進行遷移,而不是通過 緩存熱門。如果任務符合此條件,則調用pull_task()以 將任務從最繁忙的runqueue拉到當前的runqueue。

只要runqueues保持不平衡,前兩個步驟是 重複和更多的任務從最繁忙runqueue拉動到 電流。最後,當不平衡被解決時,當前運行隊列 被解鎖並且load_balance()返回。

代碼以下

static int load_balance(int this_cpu, runqueue_t *this_rq, 
         struct sched_domain *sd, enum idle_type idle) 
{ 
     struct sched_group *group; 
     runqueue_t *busiest; 
     unsigned long imbalance; 
     int nr_moved; 

     spin_lock(&this_rq->lock); 

     group = find_busiest_group(sd, this_cpu, &imbalance, idle); 
     if (!group) 
       goto out_balanced; 

     busiest = find_busiest_queue(group); 
     if (!busiest) 
       goto out_balanced; 

     nr_moved = 0; 
     if (busiest->nr_running > 1) { 
       double_lock_balance(this_rq, busiest); 
       nr_moved = move_tasks(this_rq, this_cpu, busiest, 
             imbalance, sd, idle); 
       spin_unlock(&busiest->lock); 
     } 
     spin_unlock(&this_rq->lock); 

     if (!nr_moved) { 
       sd->nr_balance_failed++; 

       if (unlikely(sd->nr_balance_failed > sd->cache_nice_tries+2)) { 
         int wake = 0; 

         spin_lock(&busiest->lock); 
         if (!busiest->active_balance) { 
           busiest->active_balance = 1; 
           busiest->push_cpu = this_cpu; 
           wake = 1; 
         } 
         spin_unlock(&busiest->lock); 
         if (wake) 
           wake_up_process(busiest->migration_thread); 
         sd->nr_balance_failed = sd->cache_nice_tries; 
       } 
     } else 
       sd->nr_balance_failed = 0; 

     sd->balance_interval = sd->min_interval; 

     return nr_moved; 

out_balanced: 
     spin_unlock(&this_rq->lock); 

     if (sd->balance_interval < sd->max_interval) 
       sd->balance_interval *= 2; 

     return 0; 
} 

什麼我不明確的是在上面的代碼結構sched_domain的結構* 這個結構我查 定義SD在include/linux/sched.h中作爲如下: http://lxr.linux.no/linux+v3.7.1/include/linux/sched.h#L895 它是一個很大的結構,所以我剛剛給出了一個簡單的鏈接。 我想知道的是在上面的代碼中使用struct sched_domain是什麼?

爲什麼在調用load_balancer()時這個結構代表什麼?

這裏給出的一些東西可能是 http://www.kernel.org/doc/Documentation/scheduler/sched-domains.txt 爲什麼CPU需要調度域?這些領域代表什麼?

回答

13

調度域和調度組/ CPU組有助於緩解像調度任務的 過程:

  1. 在CPU負載均衡任務。
  2. 選擇要運行的新任務的cpu。
  3. 選擇一個睡眠任務的CPU在喚醒時運行。

它具有雙重的優勢:

  1. 它組織系統很好分組和層次結構的處理器。

  2. 它組織以這樣的方式CPU的,這是useful.All的CPU,其
    共享的L2高速緩存屬於一個domain.All的CPU共享L3高速緩存
    屬於一個更高層次的結構域,其包括所有的域共享l2緩存。

你與像數據結構的樹中看到的效果與 這裏調度域和集團的優勢。

請參考下圖

 _________sd1________ 
    /     \ 
    ---------------------- 
     l3 cache 
    ---------------------- 
    --------- ---------- 
    l2 cache l2 cache 
    --------- ---------- 
    cpu0 cpu1 cpu2 cpu3 
    \_______/ \________/ 
     sd0   sd0 

________sd1_________ 
/     \ 
---------------------- 
     l3 cache 
---------------------- 
--------- ---------- 
l2 cache l2 cache 
--------- ---------- 
cpu4 cpu5 cpu6 cpu7 
\_______/ \________/ 
    sd0   sd0 

什麼你在上面看到的是一個調度域hierarchy.sd1包括sd0s 而它們恰巧是sd1.Every CPU的調度組具有與之相關聯的調度 域層次結構。例如。
cpu0-> sd = sd0; sd0-> parent = sd1.通過鏈表,我們可以通過 遍歷CPU所屬的所有調度程序域。

這有什麼用?

1.load平衡:說CPU0處於閒置狀態,並準備去拉任務時 本身,以減輕任何其他負擔cpu.In上面的方法,它首先 檢查是否屬於第一級域附表其它CPU ,需要解除load.Here,cpu1。如果是這樣,它將從 cpu1中執行任務,否則它會轉到更高級別的域sd1。如果它選擇 從cpu1遷移任務,這是最好的選擇,因爲可以使用高速緩存內容 ;共享高速緩衝存儲器。無需再次從存儲器獲取。這是第一優點:基於硬件必須提供的優勢 形成調度域。

,如果去SD1,那麼它探測SD1的「羣體」,無論是sd0s.Here是 下一advantage.It大概需要單獨附表組和 信息不會理會在it.it各個CPU檢查是否 加載(sd0 [cpu2,cpu3])>加載(sd0 [cpu0,cpu1]) 只有在這種情況下才會繼續查看cpu2/3是否更加加載。如果 沒有調度程序域或組,我們必須在兩次迭代中看到cpu2和cpu3的狀態 ,而不是1次迭代,就像我們現在正在做的 一樣。

現在將這個問題和解決方案擴展到128 cpu!想象一下,如果沒有什麼可以告訴你哪個cpu是最好的,以減輕負載,那麼最糟糕的情況下,你將不得不通過所有128 cpu重複 。

但是隨着調度域或組,說你劃分128個CPU爲 組的16個CPU,你將有8 groups.see這是最忙的,所以 這將是8次迭代,然後你就會知道最繁忙組,然後 下降。另外16次迭代。所以最壞情況下

8 + 16 = 24次迭代。並且這種減少僅與一個級別的sched 域相關。想象一下,如果你有更多的水平,你會使得迭代次數更低。

所以簡而言之,調度程序域和組是「分而治之 ;但儘可能地克服什麼是更有用的」解決方案,以調度相關的東西 。

我張貼的情況下,未來有人可能想要閱讀它。