思路:

  只保留奇数

  (1)由输入的整数n确定存储奇数(不包括1)的数组大小:

n=(n%2==0)?(n/2-1):((n-1)/2);//n为存储奇数的数组大小,不包括基数1

  (2)由数组大小n、进程号id和进程数p,确定每个进程负责的基数数组的第一个数、最后一个数和数组维度:

low_value = 3 + 2*(id*(n)/p);//进程的第一个数

  high_value = 3 + 2*((id+1)*(n)/p-1);//进程的最后一个数

  size = (high_value - low_value)/2 + 1;  //进程处理的数组大小

  (3)寻找奇数的第一个倍数的下标,经过反复思考,有如下规律:

  if (prime * prime > low_value)

  first = (prime * prime - low_value)/2;

  else {

  if (!(low_value % prime))

first = 0;

  else

first=((prime-low_value%prime)%2==0)?((prime-low_value%prime)/2):((prime-low_value%prime+prime)/2);

}

  code:

 #include "mpi.h"
#include <math.h>
#include <stdio.h>
#define MIN(a,b) ((a)<(b)?(a):(b)) int main (int argc, char *argv[])
{
int count; /* Local prime count */
double elapsed_time; /* Parallel execution time */
int first; /* Index of first multiple */
int global_count; /* Global prime count */
int high_value; /* Highest value on this proc */
int i;
int id; /* Process ID number */
int index; /* Index of current prime */
int low_value; /* Lowest value on this proc */
char *marked; /* Portion of 2,...,'n' */
int n,m; /* Sieving from 2, ..., 'n' */
int p; /* Number of processes */
int proc0_size; /* Size of proc 0's subarray */
int prime; /* Current prime */
int size; /* Elements in 'marked' */ MPI_Init (&argc, &argv); /* Start the timer */ MPI_Comm_rank (MPI_COMM_WORLD, &id);
MPI_Comm_size (MPI_COMM_WORLD, &p);
MPI_Barrier(MPI_COMM_WORLD);
elapsed_time = -MPI_Wtime(); if (argc != ) {
if (!id) printf ("Command line: %s <m>\n", argv[]);
MPI_Finalize();
exit ();
} n = atoi(argv[]);
m=n;//
n=(n%==)?(n/-):((n-)/);//将输入的整数n转换为存储奇数的数组大小,不包括奇数1
//if (!id) printf ("Number of odd integers:%d Maximum value of odd integers:%d\n",n+1,3+2*(n-1));
if (n==) {//输入2时,输出1 prime,结束
if (!id) printf ("There are 1 prime less than or equal to %d\n",m);
MPI_Finalize();
exit ();
}
/* Figure out this process's share of the array, as
well as the integers represented by the first and
last array elements */ low_value = + *(id*(n)/p);//进程的第一个数
high_value = + *((id+)*(n)/p-);//进程的最后一个数
size = (high_value - low_value)/ + ; //进程处理的数组大小 /* Bail out if all the primes used for sieving are
not all held by process 0 */ proc0_size = (n-)/p; if (( + *(proc0_size-)) < (int) sqrt((double) (+*(n-)))) {//
if (!id) printf ("Too many processes\n");
MPI_Finalize();
exit ();
} /* Allocate this process's share of the array. */ marked = (char *) malloc (size); if (marked == NULL) {
printf ("Cannot allocate enough memory\n");
MPI_Finalize();
exit ();
} for (i = ; i < size; i++) marked[i] = ;
if (!id) index = ;
prime = ;//从素数3开始
do {
//确定奇数的第一个倍数的下标
if (prime * prime > low_value)
first = (prime * prime - low_value)/;
else {
if (!(low_value % prime))
first = ;
else
first=((prime-low_value%prime)%==)?((prime-low_value%prime)/):((prime-low_value%prime+prime)/);
} for (i = first; i < size; i += prime) marked[i] = ;
if (!id) {
while (marked[++index]);
prime = *index + ;//下一个未被标记的素数
}
if (p > ) MPI_Bcast (&prime, , MPI_INT, , MPI_COMM_WORLD);
} while (prime * prime <= +*(n-));// count = ;
for (i = ; i < size; i++)
if (!marked[i]) count++;
if (p > ) MPI_Reduce (&count, &global_count, , MPI_INT, MPI_SUM,
, MPI_COMM_WORLD); /* Stop the timer */ elapsed_time += MPI_Wtime(); /* Print the results */ if (!id) {
printf ("There are %d primes less than or equal to %d\n",
global_count+, m);//前面程序是从素数3开始标记,忽略了素数2,所以素数个数要加1
printf ("SIEVE (%d) %10.6f\n", p, elapsed_time);
}
MPI_Finalize ();
return ;
}

查找素数Eratosthenes筛法的mpi程序的更多相关文章

  1. 用C++实现的增强Eratosthenes筛法程序

    运行示例 PS H:\Read\num\x64\Release> .\eSievePro Eratosthenes sieve: a method to find out all primes ...

  2. 用C++实现的Eratosthenes筛法程序

    运行示例 只输出素数总数的运行示例 PS H:\Read\num\x64\Release> .\esieve.exe Eratosthenes sieve: a method to find o ...

  3. 素数筛法(Eratosthenes筛法)

    介绍 Eratosthenes筛法,又名埃氏筛法,对于求1~n区间内的素数,时间复杂度为n log n,对于10^6^ 以内的数比较合适,再超出此范围的就不建议用该方法了. 筛法的思想特别简单: 对于 ...

  4. 素数筛 : Eratosthenes 筛法, 线性筛法

    这是两种简单的素数筛法, 好不容易理解了以后写篇博客加深下记忆 首先, 这两种算法用于解决的问题是 : 求小于n的所有素数 ( 个数 ) 比如 这道题 在不了解这两个素数筛算法的同学, 可能会这么写一 ...

  5. 由Eratosthenes筛法演变出的一种素数新筛法

    这两天和walls老师交流讨论了一个中学竞赛题,我把原题稍作增强和变形,得到如下一个题: 从105到204这100个数中至少要选取多少个数才能保证选出的数中必有两个不是互素的? 我们知道最小的几个素数 ...

  6. 【NYOJ-187】快速查找素数—— 枚举法、筛选法、打表法

    快速查找素数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 现在给你一个正整数N,要你快速的找出在2.....N这些数里面所有的素数. 输入 给出一个正整数数N(N ...

  7. nyoj_187_快速查找素数_201312042102

    快速查找素数 时间限制:1000 ms  |           内存限制:65535 KB 难度:3   描述 现在给你一个正整数N,要你快速的找出在2.....N这些数里面所有的素数.   输入 ...

  8. NYOJ--187--快速查找素数(筛选法,素数打表)

    快速查找素数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 现在给你一个正整数N,要你快速的找出在2.....N这些数里面所有的素数.   输入 给出一个正整数数N ...

  9. nyoj---快速查找素数

    快速查找素数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 现在给你一个正整数N,要你快速的找出在2.....N这些数里面所有的素数.   输入 给出一个正整数数N ...

随机推荐

  1. Spark 生态系统组件

    摘要: 随着大数据技术的发展,实时流计算.机器学习.图计算等领域成为较热的研究方向,而Spark作为大数据处理的“利器”有着较为成熟的生态圈,能够一站式解决类似场景的问题.那你知道Spark生态系统有 ...

  2. 查看Windows下引起Oracle CPU占用率高的神器-qslice

    前言: qslice是一个win2000的工具包,能分析进程的cpu占用率,我们用于分析oracle的性能 这是绿色的软件无需安装. 我们经常会碰到oracle的CPU占用居高不下,无法快速定位到问题 ...

  3. js倒计时-倒计输入的时间

    计算指定时间到指定时间之间相差多少天.时.分.秒. 节日.活动.商城常用. 原理: 主要使用到时间戳,也就是从1970 年 1 月 1 日 到指定时间的毫秒数. 1. 求出毫秒差 :当两个时间直接进行 ...

  4. PagerSlidingTabStrip介绍及使用,让ViewPager更绚丽

    转载请注明出处http://blog.csdn.net/harryweasley/article/details/42290595,谢谢. 以前一直想着,ViewPager中间的那个横线怎么跟着屏幕的 ...

  5. 数据结构笔记--栈的总结及java数组实现简单栈结构

    杂谈"栈"结构: 栈(Stack)是一种插入删除操作都只能在一个位置上进表,这个位置位于表的末端,叫做栈顶(Top). 对栈的基本操作有push和pop,表示进栈和出栈.也就相当于 ...

  6. JavaScript instanceof vs typeof

    Use instanceof for custom typesvar ClassFirst = function () {};var ClassSecond = function () {};var ...

  7. Hive读取外表数据时跳过文件行首和行尾

    作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 有时候用hive读取外表数据时,比如csv这种类型的,需要跳过行首或者行尾一些和数据无关的或者自 ...

  8. DDD及相关概念

    领域:指一个具体的应用范围,比如电商.订票管理.会议管理等,实现某一领域的功能,与其对应的商业领域一致.譬如Contoso会议管理系统从两个方面来阐述(1)系统概览:销售会议座位.创建新会议[领域的活 ...

  9. 认识W3C标准盒子模型,理解外边距叠加

    概述: 注:加粗斜体字是非常重要的概念,决定着你是不是能看懂那句话,所以不懂的请一定要搜索一下. 页面上的每个元素,都在一个矩形框里.   每个矩形框都是一个盒模型.   每个盒模型都由内容区域(co ...

  10. 在mongoose中使用$match对id失效的解决方法

    Topic.aggregate( //{$match:{_id:"5576b59e192868d01f75486c"}}, //not work //{$match:{title: ...