2009-09-09 75 views
11

我有一個簡單的bash腳本,它將一個進程的輸出管道傳輸到另一個進程。即:。如何在多核上運行使用bash進行管理的進程?

dostuff | filterstuff 

在我的Linux系統上(openSUSE,如果有問題的話,內核2.6.27),這兩個進程都運行在一個內核上。但是,運行不同過程在不同的內核是不會發生在這種情況下觸發默認策略。

什麼組件系統的負責人認爲,我應該怎樣做才能利用多核功能?

注意,有對2.6.30內核沒有這樣的問題。

澄清:具有其次Dennis Williamson的建議,我做了肯定與頂級方案,即管道輸送過程確實總是在同一處理器上運行。 Linux調度程序通常做得非常好,但這次不行。

我想的東西在bash阻止OS從這樣做。事情是,我需要一個便攜式解決方案的多核心和單核心機器。通過Dennis Williamson提出的tasksetsolution不會在單核機工作。目前我正在使用:,

dostuff | taskset -c 0 filterstuff 

但這似乎是一個骯髒的黑客攻擊。有誰能提供更好的解決方案嗎?

+0

嘗試用'top'重複測試幾次(不包括'taskset')。當我這樣做時,有時這兩個進程在同一個CPU上,有時是不同的。 – 2009-09-09 13:49:05

+0

他們總是在同一個系統上,只使用系統的50%:( – 2009-09-09 14:17:14

+1

嘗試'(dostuff)|(filterstuff)',看看他們顯示了哪個核心。一個區別(如果有的話)是你在多核系統上,我在多處理器(每個單核)系統上,爲什麼要分開這些進程呢?它們是你編寫的程序嗎?你可以改變它們以便它們自己影響調度器嗎? – 2009-09-09 14:36:55

回答

7

假設dostuff正在一個CPU上運行。它將數據寫入管道,並且該數據將在該CPU的緩存中。由於filterstuff正在從該管道讀取,因此調度程序決定在同一CPU上運行它,以便其輸入數據已存在於高速緩存中。

如果你的核心是建立與CONFIG_SCHED_DEBUG=y

# echo NO_SYNC_WAKEUPS > /sys/kernel/debug/sched_features

應禁用這類啓發式的。 (有關其他調度程序可調參數,請參見/usr/src/linux/kernel/sched_features.h/proc/sys/kernel/sched_*。)

如果幫助,這個問題仍然較新的內核,它的真正更快地在不同的CPU數量多於一個CPU運行的情況下,請將該問題報告給Linux內核郵件列表,以便他們能夠調整自己的啓發式。

+0

NO_SYNC_WAKEUPS工作。但是,內核是2.6.27,而在2.6.30系統上似乎沒有出現這個問題。我會進一步調查。 – 2009-09-10 09:47:17

+0

無法在2.6.30上重現它。進程在具有和不具有SYNC_WAKEUPS的核心之間反彈。 – 2009-09-11 20:07:28

+0

好吧,我解決了這個問題。由於我的產品沒有很多用戶,並且它們的內核編譯得很好,所以我可以讓他們按照您提供的方式調整它們。謝謝。 – 2009-09-12 15:55:08

7

試試這個設置CPU(處理器)的親和力:

taskset -c 0 dostuff | taskset -c 1 filterstuff 

編輯:

試試這個實驗:

  • 創建一個名爲proctest和chmod +x proctest以此爲內容:

    #!/bin/bash 
    while true 
    do 
        ps 
        sleep 2 
    done 
    
  • 啓動這個運行:

    ./proctest | grep bash 
    
  • 在另一端
  • ,開始頂 - 確保它的排序由%CPU
  • 讓它沉澱幾秒鐘,然後退出
  • 發出命令ps u
  • top -p開始top -p帶有最高的幾個進程的PID的列表,其中8個是從退出的top屏幕上的列表加上01的那個和其通過ps列出grep - 所有由逗號分隔的,像這樣(在順序無關緊要):

    top -p 1234, 1255, 1211, 1212, 1270, 1275, 1261, 1250, 16521, 16522 
    
  • 添加處理器字段 - 按˚F然後Ĵ然後空間
  • 設置排序,以PID - 按 + ˚F然後一個然後空間
  • 可選的:按 + ħ開啓螺紋視圖
  • 可選的:按d並鍵入.09並按輸入設置一個短的延遲時間
  • 現在觀看作爲處理移動從處理器到處理器,您應該看到proctestgrep反彈,有時在同一個處理器上,有時在不同的處理器上
+0

令人驚歎!有用。但是,嗯,爲什麼我不能避免手動分配給內核? – 2009-09-09 10:01:54

+2

有關更多信息,請參閱'man sched_setscheduler'和'man cpuset'。 Linux在調度方面做得很好。嘗試運行'top'並按fj 添加處理器(P)字段,您將看到不同的進程正在不同的CPU上運行。 – 2009-09-09 10:39:34

+0

您也可以按'top'中的'1'(one)來查看頂部每個CPU的CPU負載。 – 2009-09-09 10:45:36

1

Linux調度程序旨在提供最大的吞吐量,而不是做你認爲最好的。如果您正在運行與管道連接的進程,很有可能其中一個進程阻塞了另一個進程,然後它們會交換。在單獨的核心上運行它們會獲得很少或沒有任何效果,所以它不會。

如果你有兩個任務都是真正可以在CPU上運行的,我希望看到它們被安排在不同的內核上(某些時候)。

我的猜測是,dostuff會一直運行,直到管道緩衝區變滿爲止,此時它不能再運行,所以「filterstuff」進程會運行,但運行的時間很短,以至於dostuff直到filterstuff完成對整個管道緩衝區的過濾之後纔會重新計劃,此時dostuff會再次進行調度。

+0

你的猜測是錯誤的。這些過程像這樣運行:'dostuff'佔用核心CPU時間的60%,'filterstuff'佔用剩餘的40%。並且在運行幾分鐘後它們不會重新安排到不同的核心。 – 2009-09-09 22:14:55

+0

那麼公平的,只是一個想法。 – MarkR 2009-09-10 20:32:30

相關問題