ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 跨平台并行库的初步设计

跨平台并行库的初步设计

原创 Linux操作系统 作者:yu_single 时间:2010-05-25 16:29:17 0 删除 编辑
Normal 0 false false false EN-US ZH-CN X-NONE  Normal 0 false false false EN-US ZH-CN X-NONE   上篇日志提到我想用ACELoki库设计一个类似OpenMP的并行库,前两天仔细想了想,勾勒出了大体的框架,以供讨论;)

    看下面代码之前,首先要熟悉Loki库里面对Functor模板类的使用(《C++设计新思维》一书有详细描述,不过看此书要做好心理准备:)),否则看了也是一头雾水; ACE的部分暂未描述出来,先将其隐藏在ParallelTask 类当中,所以对ACE不了解也没关系。


             结合下面代码,先把各个类的功能说一下:
              (1) 函数Task1、仿函数Task2和类Task3中的成员函数 这三种形式基本列出了C++中具有函数功能的几种表示形式,而执行一个函数就是执行一项任务。下面都将以任务的概念来描述串行和并行。另外,这里返回值都用了void,并且没有传入传出参数是因为这些都是抽象出来的概念,最终总是有办法把任务抽象到这几种形式的。
            
              (2)关于typedef Loki::Functor<> SerialTask,这里用了Loki::Functor<>,详细的我不解释了,看书吧,大概的用处就是用了这个模板类,可以把上面三种(实际有更多)函数形式完美的包装进去,令函数执行预备工作(准备对象和输入参数等等这些事情)和执行过程(就是执行函数体)分离开来,这样我们就可以把任务的准备期和执行期很好的分离,方便宏观设计。如果了解设计模式中的Command模式,应该会很快领悟到。另外利用一个Chain模板函数,此模板类还可以把各个任务方便的串行起来,以实现串行功能,故在此将其typedef为SerialTask。
            
              (3)关于类
ParallelTask,顾名思义,这个类就是具有并行功能类,我可以通过其PushTask成员函数方便的把任务塞给它,这些任务都将并行执行。而让它们何时执行,可以通过调用operator()来触发。此类也可以当作一个任务(由众多小任务组成)来看待,而且有了operator(),也可以方便的交由SerialTask对象来将它与其它任务串行起来。这个类背后的实现会用到ACE,因为ACE本身具有很强大的跨平台的多线程库。

              (4)
Sample1_2_3() 、 Sample1_23()  、Sample1_23() 、 Sample123()  是我写的几个例子,通过这几个例子可以更容易理解我的设计意图。
  1. void Task1();  
  2. struct Task2 
  3. {  
  4.     void operator()();  
  5. };  
  6. struct Task3  
  7. {  
  8.     void MemberFun();  
  9. }; 

  10. typedef Loki::Functor<> SerialTask;  
  11.   
  12. class ParallelTask  
  13. {  
  14. public:  
  15.     ParallelTask(bool bWait = true); 
  16.     void operator()();  
  17.     void PushTask(const SerialTask& st);  
  18. private:  
  19.     vector m_serialTaskVec;  
  20.     bool m_bWait;  
  21. };  
  22.   
  23. SerialTask subTask1(Task1);    // subTask1对象将会运行Task1()函数。
  24.   
  25. Task2 t2;  
  26. SerialTask subTask2(t2);    // subTask2对象将会运行t2(),也就是执行t2::operator()。
  27.   
  28. Task3 t3;  
  29. SerialTask subTask3(&t3, &Task3::MemberFun);  // subTask3对象将会t3.MemberFun()
  30.   
  31. SerialTask subTask1_2(Chain(subTask1, subTask2));  // subTask1_2对象将会串行执行subTask1和subTask2,也就是先执行Task1(),接着执行t2::operator()
  32.   
  33. SerialTask subTask1_2_3(Chain(subTask1_2, subTask3));   // subTask1_2_3对象将会串行执行subTask1、subTask2和subTask3,也就是先执行Task1(),接着执行t2::operator(),最后执行t3.MemberFun()
  34.  
  35. // 此函数通过调用subTask1_2_3()来串行执行任务1,2,3
  36. void Sample1_2_3()  
  37. {  
  38.     subTask1_2_3();  
  39. }  
  40.  
  41. // 此函数表示先执行任务1,然后并行执行任务2和3
  42. void Sample1_23()  
  43. {  
  44.     ParallelTask pt;  
  45.     pt.PushTask(subTask2);  
  46.     pt.PushTask(subTask3);  
  47.   
  48.     SerialTask st(Chain(subTask1, pt));  // 注意此处pt作为一个串行任务加入进去
  49.   
  50.     st();  
  51. }  

  52.  // 此函数表示然后并行执行任务1,2和3
  53. void Sample123()  
  54. {  
  55.     ParallelTask pt;  
  56.     pt.PushTask(subTask1);  
  57.     pt.PushTask(subTask2);  
  58.     pt.PushTask(subTask3);  
  59.       
  60.     pt();  

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7364811/viewspace-663714/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2010-05-20

  • 博文量
    7
  • 访问量
    17964