利用OpenMP實現埃拉託斯特尼(Eratosthenes)素數篩法並行化 分類: 算法與數據結構 2015-05-09 12:24 157人閱讀 評論(0) 收藏

1.算法簡介

1.1篩法起源

篩法是一種簡單檢定素數的算法。聽說是古希臘的埃拉託斯特尼(Eratosthenes,約公元前274~194年)發明的,又稱埃拉託斯特尼篩法(sieve of Eratosthenes)。ios

1.2篩法過程

具體作法是:給出要篩數值的範圍 n,找出 n 之內的素數p1,p2,p3,……,pk。從最小素數2去篩,即把2留下,把2的倍數剔除掉;再用下一個素數,也就是3篩,把3留下,把3的倍數剔除掉;接下去用下一個素數5篩,把5留下,把5的倍數剔除掉;不斷重複下去。算法

2.實現代碼

代碼爲Linux平臺,可簡單修改移植到Windows。使用OpenMP實現簡單的並行加速,有關OpenMP的用法,百度搜索「OpenMP簡易教程」。markdown

#include <cmath>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <sys/time.h>
#include <cassert>
#include <omp.h>
using namespace std;
typedef unsigned int uint32;
typedef unsigned long long int uint64;

inline void sieve(uint64 start,uint64 end,uint64& num,int threadNum)
{
  assert(start>1);
  bool* a =new bool[end+1];
  memset(a+2,true,end+1);

  #pragma omp parallel for num_threads(threadNum)
  for (uint64 i = 2; i <=(uint64)sqrt(end); i++)
  {
    if (a[i])
      for (uint64 j = i; i*j <= end; j++) 
        a[i*j] = false;
  }
  uint64 prime_num=0;
  if(start==2)
    prime_num++;

  #pragma omp parallel for num_threads(threadNum) reduction(+: prime_num)
  for (uint64 i =(start%2==0?start+1:start); i <=end ;i += 2)
  {
    if (a[i])
      prime_num++;
  }
  num=prime_num;
  delete[] a;
} 

int main(int argc,char* argv[])
{
    if(argc!=4){
      fprintf(stderr, "usage: Eratosthenes start_number end_number threadNum\n");
      exit(-1);
    }
    struct timeval ts,te;
    uint64 start=atoi(argv[1]);
    uint64 end=atoi(argv[2]);
    int threadNum=atoi(argv[3]);
    uint64 num=0;
    gettimeofday(&ts,NULL);
    sieve(start,end,num,threadNum);
    gettimeofday(&te,NULL);
    cout<<"count: "<<num<<endl;
    cout<<"total time: "<<((te.tv_sec-ts.tv_sec)*1000+(te.tv_usec-ts.tv_usec)/1000)<<"ms"<<endl;
    getchar();
    return 0;
}

參考文獻

[1]百度百科-篩法ui

版權聲明:本文爲博主原創文章,未經博主容許不得轉載。spa

相關文章
相關標籤/搜索