C#/ C ++中的同步并行处理

时间:2015-12-25 08:20:47

标签: c# c++ multithreading parallel-processing synchronous

我有一个包含数据的数组x []。还有一系列“系统状态”c []。过程:

for(i = 1; i < N; i++)
{   
  a = f1(x[i] + c[i-1]);
  b = f2(x[i] + c[i-1]);
  c[i] = a + b;
}

是否有任何有效的方法可以使用2个并行线程在2核系统上查找f1f2的值?我的意思是以下(伪代码):

thread_1
{
    for(i = 1; i < N; i++)
      a = f1(x[i] + c[i-1]);    
}
thread_2
{
    for(i = 1; i < N; i++)
    {
      b = f2(x[i] + c[i-1]);
      c[i] = a + b;  //here we somehow get a{i} from thread_1
    }
}

f1f2不是时间消耗,但必须多次计算,因此所需的加速比约为x2。请参见图表以获取图形表示:

desired parallel process

寻找Windows的代码示例。

3 个答案:

答案 0 :(得分:4)

如果我理解你的话,

  • <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <body> <div id="container"> <header> <h1>jQuery Content Slider</h1> </header> <img src="http://leedspromoproducts.com/templates//img/thumbnails_prev_button.png" alt="Prev" id="prev"> <div id="slider"> <div class="slide"> <div class="slide-copy"> <h2>Slider One</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae commodo sem. Integer eros nibh, molestie congue elementum quis, mattis nec tortor. Vivamus sed hendrerit sed vitae orci convallis.</p> </div> <img src="http://www.vectordiary.com/isd_premium/048-hot-air-balloon/hot-air-balloon.jpg"> </div> <div class="slide"> <div class="slide-copy"> <h2>Slider Two</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae commodo sem. Integer eros nibh, molestie congue elementum quis, mattis nec tortor. Vivamus sed hendrerit sed vitae orci convallis.</p> </div> <img src="http://www.moneyindices.com/admin/upload/50193693.jpg"> </div> <div class="slide"> <div class="slide-copy"> <h2>Slider Three</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae commodo sem. Integer eros nibh, molestie congue elementum quis, mattis nec tortor. Vivamus sed hendrerit sed vitae orci convallis.</p> </div> <img src="http://images.china.cn/attachement/jpg/site1007/20110808/000cf1a48f870fa9c75c55.jpg"> </div> <div class="slide"> <div class="slide-copy"> <h2>Slider Four</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae commodo sem. Integer eros nibh, molestie congue elementum quis, mattis nec tortor. Vivamus sed hendrerit sed vitae orci convallis.</p> </div> <img src="http://cdn.allsteamboat.com/images/content/5418_gBVhd_Hot_Air_Balloon_Rodeo_in_Steamboat_Springs_md.jpg"> </div> <div class="slide"> <div class="slide-copy"> <h2>Slider Five</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae commodo sem. Integer eros nibh, molestie congue elementum quis, mattis nec tortor. Vivamus sed hendrerit sed vitae orci convallis.</p> </div> <img src="http://www.moneyindices.com/admin/upload/50193693.jpg"> </div> </div> <img src="http://thehaircraftersco.com/wp-content/uploads/2015/10/next-button.png" alt="Next" id="next"> </div> </body>只能在a[i]可用时计算
  • c[i-1]只能在b[i]可用时计算
  • c[i-1]仅在计算c[i]a[i]
  • 时可用

这意味着您可以单独执行的唯一流程是计算b[i]a[i]

我在C#中的看法:

b[i]

这将运行两个单独的线程,分别计算for (int i = 1; i < N; i++) { Task<double> calcA = Task.Factory.StartNew(() => { return f1(x[i] + c[i-1]); }); Task<double> calcB = Task.Factory.StartNew(() => { return f2(x[i] + c[i-1]); }); // .Result will block the execution and wait for both calculations to complete c[i] = calcA.Result + calcB.Result; } f1。在计算f2f1之后,它将设置f2值,并运行下一次迭代。

请注意:

  • 我使用c[i],假设您的doublef1返回f2
  • 循环从1开始,假设您有一些初始doublea[0]值。否则,b[0]会抛出异常
  • 与其他计算相比,c[i-1]f1的计算确实耗费资源且耗时较长,这只会带来改善。
  • f2(与使用Task.Factory.StartNew不同)使用ThreadPool,这意味着它不会每次都创建新线程,但会重用池中的现有线程。它显着减少了开销。

答案 1 :(得分:4)

此算法中唯一的并行部分是f1和f2的计算,但是你说f1和f2不是时间消耗的,所以使用SIMD矢量化可能要好得多(例如C#中的System.Numerics.Vectors)和在一个核心上运行它(这也减少了缓存未命中)。或者你可能会修改你的算法可以并行化(但可能需要努力工作)。

答案 2 :(得分:2)

无需进入代码解决方案,您希望使用某种障碍。这允许检查所有参与者是否已声明他们已完成任务。线程2必须在此示例中等待线程1

https://en.wikipedia.org/wiki/Barrier_(computer_science) Example of C++ "Memory barrier"