2010-05-13 84 views
6

我在具有24個內核的共享Linux計算機上運行大規模並行科學計算作業。大多數情況下,當這臺計算機上沒有其他任何內容運行時,我的作業可以擴展到24個內核。然而,看起來就像即使一個不是我的單線程作業正在運行時,我的24線程作業(我爲高漂亮值設置)也只能達到〜1800%的CPU(使用Linux符號)。同時,大約500%的CPU週期(再次使用Linux符號)是空閒的。任何人都可以解釋這種行爲,我能做些什麼來獲得所有未被別人使用的23個內核?Linux 2.6.31調度程序和多線程作業

注:

  1. 如果它是相關的,我觀察這個上略有不同的內核版本,但我不記得是哪了我的頭頂。

  2. CPU架構是x64。是否所有可能的事實是,我的24核心工作是32位的,而我正在競爭的其他工作是64位的是相關的?

編輯:我剛剛注意到的一件事是,多達30個線程似乎在一定程度上緩解了這個問題。它讓我高達2100%的CPU。

+0

如果只運行產生n個線程的單個進程,那麼只會影響您_own_的進程。您只能與單個進程競爭。這臺機器上有root/sudo可用嗎? – 2010-05-13 17:16:55

+0

如果你下降到23個線程會發生什麼情況,剩下一個內核可用於其他工作? – caf 2010-05-14 01:30:26

回答

6

這可能是由於調度程序試圖保持每個任務運行在與之前運行的CPU相同的CPU上(這是因爲任務可能將其工作集帶入該CPU的緩存 - 它是「緩存熱」)。

這裏有一些想法,你可以嘗試:

  • 運行兩倍多線程,你有核心;
  • 運行一個或兩個以上的線程比你有核心;
  • 降低/proc/sys/kernel/sched_migration_cost的值(可能降至零);
  • 減少/proc/sys/kernel/sched_domain/.../imbalance_pct下跌接近100
0

使用mpstatsysstat包的一部分)來確定整個CPU是否處於閒置狀態而其他處於充分利用狀態可能是值得的。它應該比top或vmstat提供更詳細的利用率視圖:運行mpstat -P ALL以查看每個CPU 1行。

作爲一個實驗,您可以嘗試在每個線程上設置CPU親和性,以使每個線程都綁定到單個CPU;如果不讓內核調度程序決定某個任務被安排在哪個CPU上,這可以讓您看到性能如何。這不是一個好的永久解決方案,但是如果它有很大的幫助,它可以讓你瞭解調度程序的缺點。

+0

不幸的是我沒有管理員權限,並且沒有安裝sysstat。 – dsimcha 2010-05-13 21:15:35

+1

從源代碼構建sysstat並不難。 – 2010-05-13 21:55:23

2

你的線程是否需要同步?如果是這樣,您可能會遇到以下問題:

假設您有一個4-cpu系統和一個4線程作業。單獨運行時,線程扇出使用全部4個內核,總使用率接近完美(我們將稱這爲400%)。

如果添加一個單線程干擾作業,調度程序可能會將2個線程放在同一個cpu上。這意味着你的兩個線程現在以正常速度的一半運行(戲劇性的簡化),並且如果你的線程需要定期同步,你的工作進度會受到最慢的線程的限制,在這種情況下,線程運行在正常速度的一半。你會看到利用率只有200%(從你的工作運行4x 50%)加上100%(干擾工作)= 300%。同樣,如果您認爲干擾作業只使用一個處理器時間的25%,則可能會在同一CPU上看到您的一個線程和干擾信號。在這種情況下,最慢的線程以3/4的正常速度運行,導致總利用率爲300%(4x75%)+ 25%= 325%。玩這些數字,並不難想出類似於你所看到的東西。如果這是問題,你當然可以玩優先級給予不受歡迎的任務只有很小的可用CPU(我假設I/O延遲不是一個因素)。或者,如您所見,嘗試增加線程數,使每個CPU具有2個線程,減少幾個線程以允許執行系統任務。通過這種方式,24核心系統可以運行得最好,例如46個線程(總是使系統任務的2個核心時間的一半可用)。

+0

當然,咖啡館對23條線索的建議可能比我對46條線索的建議要好,這是獲得2300%利用率的一種方式。 – 2010-05-14 14:32:12

0

值你認爲的瓶頸是應用程序或內核的調度算法?在開始調整計劃參數之前,我建議您嘗試運行一個簡單的多線程應用程序,以查看它是否展現與您的應用程序相同的行爲。

// COMPILE WITH: gcc threads.c -lpthread -o thread 
#include <pthread.h> 
#define NUM_CORES 24 

void* loop_forever(void* argument) { 
    int a; 
    while(1) a++; 
} 

void main() { 
    int i; 
    pthread_t threads[NUM_CORES]; 

    for (i = 0; i < NUM_CORES; i++) 
     pthread_create(&threads[i], 0, loop_forever, 0); 

    for (i = 0; i < NUM_CORES; i++) 
     pthread_join(threads[i], 0); 
} 
1

您的線程是否相互通信?

嘗試手動綁定每個線程到CPU,sched_setaffinitypthread_setaffinity_np。調度程序在處理大量相關的線程時可能相當愚蠢。