并行程序的几点Tips:

来源:互联网 发布:汽车电脑板维修编程 编辑:程序博客网 时间:2024/05/16 12:41

这两天在搞多线程并行, 有以下几点体会:

1   shared resource 是毒药, 尤其是在频繁需要加锁的时候。当计算的core增多时,其性能扩展不明显

2  要尽量用现成的并行framework.  .NET的TPL, c++的opencl和amp。这些framework能够形成一个thread pool, 能够根据系统当前的状况自动来schedule最佳的线程数和调度策略,任务分配等。能够使cpu一直处于满负荷的状态工作

3 并行要用coarse-grained。fine-grained会使系统创建和调度线程的cost大于真正所执行的任务的时间。在recursive 的程序尤其要注意,比如quiksort, 如果划分不合理会使并行的时间大于顺序执行的时间。

4  I/O是最耗时的部分。在多线程下同时读写多个文件,性能不会明显提高,反而会有可能降低。这个我还得仔细研究下,没怎么弄清楚。

5 如何开发non-blocking 的程序需要再去研究

6 spinlock与lock mutex的区别: spinwait不会让thread从内核中跳出,而mutex等不到的时候会使thread调出。

7 find the bottleneck and tackle it.

8  Amdahl‘s law. The most efficient time in theory.:不可并行计算的存在是很重要的,因为它将限制并行化的潜在好处。阿姆达尔定律指明如果一个计算的1/S本质上是顺序的,那么最大的性能改进将受限于因数S。其论证如下,一个并行计算的执行时间TP将是顺序部分计算时间和可并行化部分计算时间两者的和。如果该计算顺序地执行需要花费的时间是TS,则当有P个处理器时,TP可表示为S=n/[1+(n-1)f]





Task[] tasks = new Task[subcount];
for i = 0; i < subcount; i++)
{
    task[i] = Task.Factory.StartNew(convert(sub));
}

            
  Task[] allTasks = tasks;

  // Print completion notices one by one as tasks finish.
  while (tasks.Length > 0)
  {
    taskIndex = Task.WaitAny(tasks);
    //progress bar updated.
    tasks = tasks.Where((t) => t != tasks[taskIndex]).ToArray();
  }

  // Observe any exceptions that might have occurred.
  try
  {
    Task.WaitAll(allTasks);
  }
  catch (AggregateException ae)
  {
    ...
  }

原创粉丝点击