C MPI - 批量生成多个线程

标签 c mpi

我有一个关于 C 中 MPI 编程的基本问题。本质上我想要的是有一个主进程产生特定数量的子进程,从所有子进程收集一些信息(等到所有子进程完成) ,计算一些指标,根据这个指标决定是否必须产生更多线程......它一直这样做直到指标满足某些特定条件。我翻遍了文献,无果。如何才能做到这一点?任何指示?

感谢您的帮助。

礼貌:An introduction to the Message Passing Interface (MPI) using C .在“对数组求和的完整并行程序”中,可以说,“出于某种蹩脚的原因”,我希望主进程对数组的内容求和两次。即在第一次迭代中,主进程启动计算数组总和的从进程,一旦它们完成并且主进程返回值,我想调用主进程重新调用另一组线程来执行再次计算。为什么下面的代码不起作用?我在生成从属进程的主进程周围添加了一个 while 循环。

  #include <stdio.h>
  #include <mpi.h>

  #define max_rows 100000
  #define send_data_tag 2001
  #define return_data_tag 2002

  int array[max_rows];
  int array2[max_rows];

main(int argc, char **argv) 
 {
   long int sum, partial_sum,number_of_times;

  number_of_times=0;

  MPI_Status status;

  int my_id, root_process, ierr, i, num_rows, num_procs,
     an_id, num_rows_to_receive, avg_rows_per_process, 
     sender, num_rows_received, start_row, end_row, num_rows_to_send;

  /* Now replicte this process to create parallel processes.
   * From this point on, every process executes a seperate copy
   * of this program */

  ierr = MPI_Init(&argc, &argv);

  root_process = 0;

  /* find out MY process ID, and how many processes were started. */

  ierr = MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
  ierr = MPI_Comm_size(MPI_COMM_WORLD, &num_procs);

  if(my_id == root_process) {

     /* I must be the root process, so I will query the user
      * to determine how many numbers to sum. */

     //printf("please enter the number of numbers to sum: ");
     //scanf("%i", &num_rows);

      num_rows=10;

      while (number_of_times<2)
      {

      number_of_times++;
      start_row=0;
      end_row=0;



     if(num_rows > max_rows) {
        printf("Too many numbers.\n");
        exit(1);
     }

     avg_rows_per_process = num_rows / num_procs;

     /* initialize an array */

     for(i = 0; i < num_rows; i++) {
        array[i] = i + 1;
     }

     /* distribute a portion of the bector to each child process */

     for(an_id = 1; an_id < num_procs; an_id++) {
        start_row = an_id*avg_rows_per_process + 1;
        end_row   = (an_id + 1)*avg_rows_per_process;

        if((num_rows - end_row) < avg_rows_per_process)
           end_row = num_rows - 1;

        num_rows_to_send = end_row - start_row + 1;

        ierr = MPI_Send( &num_rows_to_send, 1 , MPI_INT,
              an_id, send_data_tag, MPI_COMM_WORLD);

        ierr = MPI_Send( &array[start_row], num_rows_to_send, MPI_INT,
              an_id, send_data_tag, MPI_COMM_WORLD);
     }

     /* and calculate the sum of the values in the segment assigned
      * to the root process */

     sum = 0;
     for(i = 0; i < avg_rows_per_process + 1; i++) {
        sum += array[i];   
     } 

     printf("sum %i calculated by root process\n", sum);

     /* and, finally, I collet the partial sums from the slave processes, 
      * print them, and add them to the grand sum, and print it */

     for(an_id = 1; an_id < num_procs; an_id++) {

        ierr = MPI_Recv( &partial_sum, 1, MPI_LONG, MPI_ANY_SOURCE,
              return_data_tag, MPI_COMM_WORLD, &status);

        sender = status.MPI_SOURCE;

        printf("Partial sum %i returned from process %i\n", partial_sum, sender);

        sum += partial_sum;
     }

     printf("The grand total is: %i\n", sum);


      }



  }

  else {

     /* I must be a slave process, so I must receive my array segment,
      * storing it in a "local" array, array1. */

     ierr = MPI_Recv( &num_rows_to_receive, 1, MPI_INT, 
           root_process, send_data_tag, MPI_COMM_WORLD, &status);

     ierr = MPI_Recv( &array2, num_rows_to_receive, MPI_INT, 
           root_process, send_data_tag, MPI_COMM_WORLD, &status);

     num_rows_received = num_rows_to_receive;

     /* Calculate the sum of my portion of the array */

     partial_sum = 0;
     for(i = 0; i < num_rows_received; i++) {
        partial_sum += array2[i];
     }

     /* and finally, send my partial sum to hte root process */

     ierr = MPI_Send( &partial_sum, 1, MPI_LONG, root_process, 
           return_data_tag, MPI_COMM_WORLD);
  }


  ierr = MPI_Finalize();
 }

最佳答案

您应该首先查看 MPI_Comm_spawn 和集体操作。要从旧的子进程收集信息,通常会使用 MPI_Reduce。

This stackoverflow question 也可能有帮助。

...to spawn more threads...

我猜你的意思是正确的,因为你主要使用“进程”而不是“线程”,但只是为了澄清:MPI 只处理进程而不处理线程。

我不确定您对 MPI 的了解程度 - 如果我的回答对您有帮助,或者您是否需要更多提示,请告诉我。

关于C MPI - 批量生成多个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10568845/

相关文章:

c - Bool 函数在不满足条件的情况下返回 true - 忽略 printf()

c - 检测 RE2C 中的 IP 地址

c++ - 增加 mpi 中的 CPU 数量会增加处理时间?

linux - 如何在 `mpirun` 的命令行上指定节点?

c - MPI 集体操作和进程生命周期 (C/C++)

ios - Xcode 9.1 未找到图像 : libBacktraceRecording. dylib

c - 将指向较大数组的指针分配给指向较小 VLA 的指针

c - 在C中简化二进制分数时的无限循环

c++ - 链接 : fatal error LNK1104: cannot open file 'msmpi.lib' visual studio 2010

linux - 如何运行 MPI 任务?