新手向大家请教。
最近编程碰到寻找大质数的问题,因为速度问题,就考虑到了多线程。我的笔记本cpu是第一代双核的。
我试写的一个小程序,将2百万以内的质数赋值到一个数组里。
如果不用多线程,耗时3秒多。
我用2个线程,即主线程让它计算1百万以内的,另一个线程让它计算从1百万到2百万之间的。不错,有效果,程序降到了1.7秒。
但是我又试着开了4个线程,程序也不过降到了1.4秒左右。所以我的问题是》
是不是线程开几个有个极限?到哪查这方面的知识点?
或是我的算法不对?谢谢大家了。

解决方案 »

  1.   

    单个CPU的多线程,其实就是用模拟多CPU的办法,采用CPU时间片的交替切换过程, 多个CPU针对相应多个线程是实时操作过程(非时间片交替切换)。
    知道这个后,双核可视作双CPU, 对应的两个线程,属于实时操作过程,速度自然提高一倍(相对于单线程),再继续增加线程数量,
    只会简单再回到前述的时间片交替切换过程,速度自然不会有明显提升。
    windows操作系统的线程数量当然是有极限的(对于每个进程),详见<<windows核心编程>>,你也可以试着写个循环,连续启动多个线程,看下最大线程数量。
      

  2.   

    利用多线程之所以能提高运行效率,是因为多线程使CPU资源得到了充分利用。程序所占用的CPU资源会有一个极限值,该值取决于程序要处理的任务和处理的方式,如果各个线程在运行过程中都不需要等待,极限值就是100%,线程数等于处理器的数量即可达到这个极限。
      

  3.   


    这个回复太牛啦!!!
    fox000002》 多谢啦。
    cnzdgs》 你老兄又来助人啦?呵呵。
      

  4.   


    我不妨贴个代码,有兴趣的我会加分,大家没兴趣就结贴了。
    void prim(vector<int> &v, int first, int last)
    {
        int t =1;   // how many prime numbers ?
        if (first%2==0) first++;     // begin with a odd number
        for (int i=first;i<last;i+=2)
         {
           int j = (int)sqrt((double)i);  // j 到 sqrt(i)
           if (j%2==0) j--;     // begin with is a odd number
           for (;j>2;j-=2) { if (i%j==0) break; }
           if (j<3) { t++; v.push_back(i); }
         }
    }这个算法2百万以内需3秒多。(没有加入2这个质数)
      

  5.   

    用个线程池线程数定位2,也就是cpu的个数
      

  6.   

    线程以上都说的差不多了,看以看看 <Windows核心编程>这本书,讲的很好可以从以下几个方面,在提高一下性能1. 用位操作判断奇偶数2. 把vector改为list
      

  7.   


    谢谢啦。
    1.我估计现在的编译器肯定把一些求余优化成了位操作了,不过我试试。
    2.这又什么关系吗?iterator的寻址会快?不过这个算法最终要算100位以上的大数,有些小的优化也没什么根本改变。
      

  8.   

    你的CPU为双核,2线程就是极限了,多了也没用。
    为什么4线程比2线程快?那是因为你的2线程工作量不平均,有一个线程执行时间较长(计算从1百万到2百万之间的那个)。你如果调整一下工作量,2线程也能降到1.4秒。
      

  9.   

    并不是迭代更快,而是push_back更快,对于这种大量数据,list更好,不过迭代的时候应该不如vector
      

  10.   

    并不是迭代更快,而是push_back更快,对于这种大量数据,list更好,不过迭代的时候应该不如vector
      

  11.   

    从你的代码来看,只用了push_back。这样的话就没什么差别了。list优于vector的地方在于从中间插入/删除数据而不是在尾部追加。
    我建议还是用vector效率高。在一开始resize一下,让它一次性分配足够的空间,以后push_back的时候就不会因为空间可能不够而re-alloc了。
    如果用list的话,每次push_back都要alloc一个单元,效率很低。频繁分配内存的操作应该尽量避免。
      

  12.   

    http://zh.wikipedia.org/wiki/%E7%B4%A0%E6%95%B02002年,印度人 M. Agrawal 、N. Kayal 以及 N. Saxena 提出了 AKS 質數檢驗演算法,證明了可以在多項式時間內檢驗是否為質數。
      

  13.   

    对于WinXP系统,每个进程可以创建的线程数量上限是多少啊?
      

  14.   

    在我的机子上帮你试了一下,计算1到100万间的素数,单线程。
    用你原来的vector是1.57秒,而改用list是1.81秒。
    证明了我说的是对的。
      

  15.   


    多谢啦! 我的机子上也是如此。而且我记得也是vector效率高,即使list在某些地方比ector好。
    resize估计没什么大作用,因为我用int aa[]来算,时间也提高不了许多。不过还是应该注意。(可能你是在指reserve?)
    你说到有一个线程执行时间较长,这个牛,多谢啦。
    DarknessTM》这个算法效率确实不是很高。因为至今世界上对大素数的寻找还没有十分满意的方法。
    比较成熟的是Miller-Rabin算法。不过大大素数还要经过至少50次的测试才能控制误差。也谢谢了。
      

  16.   

    如果要效率,不要用STL,用数组来保存;尽量不要用浮点运算;尽量少用条件语句。
      

  17.   

    如果是运算集中型的工作,其实多少个线程并不重要,主要是考虑如何获得更多的CPU调度时间,而一般情况下IO型的任务优先级会高于运算型的线程
    因此你可以尝试提高进程和线程优先级,同时使用某些Event事件激活线程也可以适当提高线程得到调度的机会
      

  18.   

    双核双线程,单核单线程
    -----------------------------------------------
    http://www.wantsoft.com
    隐形者软件代码交流博客
    -----------------------------------------------
      

  19.   

    不要超过CUP核数的两倍,因为线程多能保证不回让CPU空闲,但是太多会影响速度,因为有时间片的轮转以及通信问题
      

  20.   


    我试着用数组保存,提高的速度不是特别明显;
    要算大数乘法,RSA,没办法,必须用浮点数;
    为何条件语句效率会差? 一个条件语句和 一个i++,或别的语句有大的区别吗?
    至于楼上几位给的线程建议,嘿嘿,俺得再学半年才看得懂。多谢了。
      

  21.   

    线程不可能无限多的,看看线程的句柄就知道了
    线程序的句柄是一个32bit的数值所以一个操作系统的
    线程有有限的,开任意多的线程并不意味着程序的运行效率高,
    要适而可止。线程多了系统在做线程切换所消耗的累加就回越多,
    累加到一定程度的时候就会发生质的变化,会拖累程序的运行效率!
      

  22.   

    你还得考虑CPU时间片呀,不是说线程越多越好
    创建线程等还需要时间呢???
      

  23.   

    CPU数量 *2 + 2一般的最优就是这个数目,不排除有人想出好的调度算法
      

  24.   

    使用多核並行處理 ,如OpenMP
    或分解任務進行並行處理
    http://blog.csdn.net/housisong/archive/2007/01/17/1485166.aspx