将任务分配给Cilk中的线程并将线程分配给NUMA节点

时间:2013-08-25 04:18:56

标签: multithreading scheduler numa cilk cilk-plus

例如,有三个主题。

  • 为线程1分配了任务1,2和3.
  • 为线程2分配任务4,5和6.
  • 为线程3分配任务7,8和9.

任务规模不统一。分配给线程的任务具有非常相似的工作集,因此当所有这三个任务由同一个线程执行时,将有效地使用缓存。我还应该注意,任务将在具有四个节点的NUMA系统上运行。必须将四个线程中的每一个分配给系统的一个节点。

我的问题是关于负载平衡。例如,如果线程1在其他任务完成之前完成任务并且未启动任务9,我希望Cilk调度程序将任务9分配给线程1。

欢迎所有解决方案,包括Cilk Plus,OpenMP或网上免费提供的其他调度程序。

更新:必须将线程分配给NUMA系统的节点,并且必须在特定节点上分配这些线程使用的内存位置。我已成功使用libnuma与OpenMP。但是我无法找到如何使用Cilk,TBB等将线程映射到节点。如果有可能在Cilk Plus中获取生成的工作者的线程ID,我会使用numa_run_on_node(nodeid)将其映射到节点。

有关Cilk在NUMA体系结构上的可伸缩性问题的更多信息:http://www.sciencedirect.com/science/article/pii/S0167739X03001845#

1 个答案:

答案 0 :(得分: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时,它会在worker的deque的尾部按下一个符号,表示继续可用于窃取。盗贼总是从双端队长那里偷走,所以你可以保证一些工人在偷走task1_task2_task3()的继续之前会窃取main()的延续。但是,由于工人选择随机偷取哪个工人,因此无法保证在work1_task2_task3()工作之前,main()的最终延续会被盗。

巴里·坦南鲍姆(Barry Tannenbaum) 英特尔Cilk开发