`
窗户纸
  • 浏览: 18286 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

有关对耗时很大循环进行并行化优化的探讨之三:并行线程越多运行就会越快吗?

 
阅读更多


在.net framework4.0以后,出现了并行编程的概念,使用 Parallel.For(0, N, i =>{ ... },很容易就可以实现我们自定义的并行化循环操作,在并行循环体中,还可以操作外部的变量,这个特性是很多其他语言所没有的,当然其他语言,诸如JAVA之类,完全可以采用我们在第二篇所介绍的方法自己生成并行化操作。

由于.net framework使用环境的局限性,以及“庞大的身躯”,和安装时必须向微软“报到”的限制。很多开发商并不喜欢用,完全可以采用我所介绍的方式实现并行化,与微软的并行化的区别只是他的循环体是使用了lamda表达式,而我的方式是使用委托而已。再发散一下,我个人认为微软的并行化操作在并行化优化方面,多处理器利用方面会更有优势些,性能会更好。

但.Net FrameWork中对并行化并行化的最大线程数貌似并没有进行个性化限定,运行起来自然是并行任务能开多少开多少了。就并行线程数的问题,我们在某个项目中做了一个实验,具体的并行任务中既有数据库操作,又有通信操作,还包括了若干锁定资源操作,以下就是实验结果敲打

最大线程数

程序平均执行时间

单线程

31470 ms

15线程

20042 ms

5线程

20307 ms

3线程

18745 ms

2线程

18523 ms


从这个有趣的实验结果可以看出,某些应用下,似乎线程数越多,执行时间反而越慢了, 很多情况下,并行化的程序性能可能反而不如顺序执行,甚至会出现一些死锁等问题,这在微软的说明中提到了很多(见http://technet.microsoft.com/zh-cn/magazine/dd997392(VS.110).aspx),从这篇文章,我们可以看到,影响性能的因素主要有两大类:
1. 对共享资源的锁定问题:这个问题比较好理解,如果多个并行任务尝试操作被锁定的内存位置,那么后来的肯定要等待,对于考虑不很周到的代码,其结果就是比串行机制还慢.
2. 循环体内的对象运行机制问题
在微软的说明中,提到了“不安全的对象”并行化的问题,比如filestream, ui对象等,

另一个有趣的操作是数据库操作及通信操作, 其特征是自身就具有不可控的性能瓶颈,最好通过优化数据库的命令,如连表查询、存储过程等处理。
但对于懒人,或者不需要再精细优化的情况下,并行任务占据的线程数越少,对整体资源及其他任务的影响也越少,所以我们可以对已经封装的并行化类进行一下最大线程数的限制:

   class ParaLoop
    {
         ....
        private int _MaxThreadQty;

        private int _CurrentThreadQty;
        private ManualResetEvent ReqThreadEvent = new ManualResetEvent(false);
        private object _SynthreadQty = new object();

        public ParaLoop(int mtq)
        {
            _MaxThreadQty = mtq;
        }

        private void ReleaseThread()   //使用完后释放线程,并通知可以申请新线程
        {
            lock (_SynthreadQty )
            {
                _CurrentThreadQty--;
                ReqThreadEvent.Set();
            }
        }


         ~ParaLoop()
        {
            ReqThreadEvent.Set();
        }
 
        private MyParaThread RequestThread()   // 申请线程,如果达到最大数则等待,直到有新的线程可用
        {
            lock (_SynthreadQty)
            {
                if (_CurrentThreadQty < _MaxThreadQty)
                {
                    _CurrentThreadQty++;
                    return new MyParaThread();
                }
                else
                {
                    ReqThreadEvent.Reset();
                }
            }

            ReqThreadEvent.WaitOne();

            lock (_SynthreadQty)
            {
                _CurrentThreadQty++;
                return new MyParaThread();
            }            
        }

       public object ParaCompute(MyParaLoopTaskHandler loopTask, object[] inArg, int loopQty)
        {
            ...

            for (int i = 0; i < _TotalQty; i++)
            {
                MyParaThread u = RequestThread();  //由直接新建线程改为申请线程
             //   MyParaThread u = new MyParaThread();
                
            }
            _ParaEvent.WaitOne();

            return _ParaLoop_Return;
        }
  

       void u_EndTaskCallBack(bool taskRst, object retVal)
        {
           ... 

            ReleaseThread();   //有返回值表示可以释放线程了
         }
    }

 

}



分享到:
评论

相关推荐

    cypress-utils:Cy轻松并行化赛普拉斯测试并对其进行压力测试

    柏树实用程序轻松并行化赛普拉斯测试并对其进行压力测试赛普拉斯Utils是一个命令行界面,用于并行化赛普拉斯测试并对其进行压力测试。 首先,只需运行npx cypress-utils --help 。指令并行运行测试为了加快日常本地...

    C/C++笔试题(附答案,华为面试题系列)

    高调度效率和限制资源使用的好处,线程池中的线程达到最大数时,其他线程就会排队 等候。 15函数模板与类模板有什么区别? 答:函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化 必须由...

    论文研究-一种基于OpenMP的并行混合PVS算法.pdf

    该算法应用了PVSplitting(主要变例分裂)策略,自底向上将博弈树每一层的首个PV节点的每个分支的搜索线程化,利用多核CPU并行执行,并对临界区和线程调度进行了合理设计,以提高搜索效率。最后,基于一个真实的中国...

    GPU加速窦房结计算机仿真的实现及优化 (2014年)

    根据具体解算过程提出了三种并行化策略,并对其中耗时最短的策略从线程块设置、数据交换频率以及存储模式等方面进行了进一步优化。结果表明:对于500个细胞的仿真,CUDA程序较串行程序的执行时间下降了60%,进一步...

    基于OpenMP并行简约空间内点法的暂态稳定紧急控制

    算法在C++ 环境下编程实现,对关键耗时部分多线程并行计算。算例测试结果表明,所提并行算法是有效的,且与传统内点算法相比,该算法消耗的计算时间和内存更少,能够求解大规模的电力系统紧急控制问题。

    Java并发编程part2

    9.1 为什么gui是单线程化的 9.2 短期的gui任务 9.3 耗时gui任务 9.4 共享数据模型 9.5 其他形式的单线程子系统 第3部分 活跃度,性能和测试 第10章 避免活跃度危险 第11章 性能和可伸缩性 第12章 测试并发程序 第4...

    Java并发编程实践part1

    9.1 为什么gui是单线程化的 9.2 短期的gui任务 9.3 耗时gui任务 9.4 共享数据模型 9.5 其他形式的单线程子系统 第3部分 活跃度,性能和测试 第10章 避免活跃度危险 第11章 性能和可伸缩性 第12章 测试并发程序 第4...

    java后台程序源码-celerity:此项目不再维护

    线程允许您并行运行测试 *易于使用*:简单的API 便携:跨平台,得益于 JVM 非侵入性:没有浏览器窗口中断您的工作流程(在后台运行) 要求 JRuby 1.2.0 或更高版本 Java 6 安装 jruby -S gem install celerity 要...

    代码之美(中文完整版).pdf

    14.8 针对多核系统的多线程设计 14.9 误差分析与操作计数浅析 14.10 未来的研究方向 14.11 进一步阅读 第15章 漂亮的设计会给你带来长远的好处 15.1. 对于漂亮代码的个人看法 15.2. 对于CERN库的介绍 15.3. 外在美...

    JAVA并发编程实践_中文版(1-16章全)_1/4

    9.1 为什么gui是单线程化的 9.2 短期的gui任务 9.3 耗时gui任务 9.4 共享数据模型 9.5 其他形式的单线程子系统 第3部分 活跃度,性能和测试 第10章 避免活跃度危险 第11章 性能和可伸缩性 第12章 测试并发程序 第4...

    基于GPU加速的几何纹理合成方法

    然后,通过采用GPU多线程并发技术设计并行加速算法,将串行的几何理纹理合成过程并行化,这使得能够快速地生成任意尺寸的新的几何纹理。实验结果表明,本文算法不仅存储占用更小,而且能够在保证合成质量的同时,极...

    Java并发编程实践 PDF 高清版

    9.1 为什么GUI是单线程化的 9.2 短期的GUI任务 9.3 耗时GUI任务 9.4 共享数据模型 9.5 其他形式的单线程子系统 第3部分 活跃度,性能和测试 第10章 避免活跃度危险 第11章 性能和可伸缩性 第12章 测试并发程序 第4...

Global site tag (gtag.js) - Google Analytics