我试图使用MPI获取一系列数字中的所有素数。我的程序按预期工作,但我想尝试更均匀地分割工作。例如,每当我用2个处理器运行它时,秩0处理器只获得一个素数而另一个获得所有其他素数。
这是我的主要功能:
//returns 1 is a number is prime 0 otherwise
int IsPrime(int id, int number) {
int i;
if (number <=1 ) return 0;
if (number % 2 == 0 && number > 2) return 0;
for (i=3; i < number/2 ; i+=2) {
if (number % i == 0) return 0;
}
return 1;
}
以下是我的主要内容:
int main (int argc, char *argv[])
{
int count; /* Solutions found by this proc */
double elapsed_time; /* Time to find, count solutions */
int global_count; /* Total number of solutions */
int i;
int id; /* Process rank */
int p; /* Number of processes */
char hostname[1024];
MPI_Init (&argc, &argv);
MPI_Comm_rank (MPI_COMM_WORLD, &id);
MPI_Comm_size (MPI_COMM_WORLD, &p);
hostname[1023] = '\0';
gethostname(hostname, 1023);
printf("MPI rank %d on host %s\n", id, hostname);
/* Start timer */
MPI_Barrier (MPI_COMM_WORLD);
elapsed_time = - MPI_Wtime();
for(i = id ; i <= prime; i+=p)
{
//trying to divide the word done by processors
if(IsPrime(id,i))
{
printf("%d) is prime: %d \n", id, i);
count++;
}
}
MPI_Reduce (&count, &global_count, 1, MPI_INT, MPI_SUM, 0,
MPI_COMM_WORLD);
任何帮助将不胜感激!谢谢!
答案 0 :(得分:2)
这不是您原始问题的答案。您的IsPrime
功能不是最佳选择。您的函数的复杂性为O[n]
。以下函数复杂度为O [sqrt(n)]。在使用线程之前,使用以下函数代替您的函数将提升您的性能。
#include <math.h>
bool isPrime(unsigned int num){
if(num < 2){
return false;
}
unsigned int size = (unsigned int)sqrt(num);
for(unsigned int i=2 ; i <= size ; i++){
if(num % i == 0){
return false;
}
}
return true;
}
答案 1 :(得分:1)
鉴于最大的不平衡来自所有偶数,除了2不是素数,你可以跳过循环中的那些并手动添加2。这不仅可以改善负载平衡,还可以为您节省大量无论如何返回false的函数调用。
如果您还需要改善平衡,可以将数字拆分为一些固定大小的块,并在工作者之间交替使用块。找到一个好的块大小可能是一个有趣的数学练习。
我不会采用动态工作分配,因为这对MPI来说很难,特别是很难以可扩展的方式实现它。