如何让处理器拆分工作?

时间:2017-04-20 22:37:10

标签: c mpi

我试图使用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); 

任何帮助将不胜感激!谢谢!

2 个答案:

答案 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来说很难,特别是很难以可扩展的方式实现它。