2013-08-25 38 views
0

例如,有三個線程。將任務分配給Cilk中的線程並將線程分配給NUMA節點

  • 線程1分配的任務1,2,和3。
  • 線程2被分配的任務4,5,和6
  • 線程3被分配的任務7,圖8和9

任務大小不統一。分配給線程的任務具有非常相似的工作集,因此當所有這三個任務都由同一個線程執行時,緩存將被有效地使用。我還應該注意到這些任務將在具有四個節點的NUMA系統上運行。四個線程中的每一個都必須分配給系統的一個節點。

我的問題是關於負載平衡。例如,如果線程1在其他任務和任務9未啓動之前完成任務,我希望Cilk調度程序將任務9分配給線程1。

歡迎使用所有解決方案,包括Cilk Plus,OpenMP或網絡上免費提供的其他調度程序。

更新:線程必須分配給NUMA系統的節點,這些線程使用的內存位置必須分配給特定的節點。我一直在使用OpenMP成功使用libnuma。但是我無法找到如何使用Cilk,TBB等將線程映射到節點。如果可以在Cilk Plus中獲取派生工作者的線程ID,我會使用numa_run_on_node(nodeid)將其映射到節點。

有關的Cilk的可擴展性問題,對NUMA架構的更多信息:http://www.sciencedirect.com/science/article/pii/S0167739X03001845#

回答

1

做到這一點的Cilk會是這樣的正確方法:

void task1_task2_task3() 
{ 
    cilk_spawn task1(); 
    cilk_spawn task2(); 
    task3(); 
} 

void task4_task5_task6() 
{ 
    cilk_spawn task4(); 
    cilk_spawn task5(); 
    task6(); 
} 

void task7_task8_task9() 
{ 
    cilk_spawn task7(); 
    cilk_spawn task8(); 
    task8(); 
} 

int main() 
{ 
    cilk_spawn task1_task2_task3(); 
    cilk_spawn task4_task5_task6(); 
    task7_task8_task9(); 
    cilk_sync; 
    finalize_stuff(); 
    return 0; 
} 

記住cilk_spawn是一個建議,調度cilk_spawn之後的代碼可能被盜,而不是要求。當一個cilk_spawn被執行時,它會在該工作者的deque的尾部推送一個符號,以使該延續可用於竊取。盜賊總是從deque的頭部偷竊,所以你可以保證一些工人在盜取task1_task2_task3()的繼續之前偷走main()的繼續。但是,由於工作人員會選擇從哪個工作人員那裏隨便竊取,因此無法保證main()的最終延續將在task1_task2_task3()的工作之前被盜用。

巴里·坦南鮑姆
英特爾Cilk的發展

+0

每個催生'taskX()'相當於'任務(X)'具有定位自己的數據的一部分。換言之,'task(X)'必須處理先前在特定NUMA節點上分配的數據[X]。我無法通過'__cilkrts_get_worker_number()'(總是返回0)和cilk :: current_worker_id()'(無法編譯)獲得線程ID。同樣在bash中設置'CILK_NPROC'不會影響'__cilkrts_get_nworkers()'返回的值(總是返回8,我的四核英特爾系統中的邏輯cpus數)和__cilkrts_get_total_workers()總是返回23。 – Kadir