将并行处理的结果添加到共享内存

时间:2019-02-19 22:29:19

标签: c parallel-processing

在我的课堂上,我们目前正在学习并行处理。我们正在用C编写并使用Linux命令行。

在我们的练习中,我们将0到20亿的总数相加。

到目前为止,我们已经采用了一种串行方法,在该方法中,您可以计算出0-1亿和1-2亿的结果,然后将它们相加。

我们还将这两个任务分解为并行方法,从而将运行时间减半。

然后,我们将其分为4个进程(我们的班级计算机具有4个内核),每个进程加起来为20亿的1/4,然后让父函数将它们加在一起,这又将运行时间减半。这里包含C语言中的代码。

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>

void sum1b(); //sum 1 to 1 billion
void sum2b(); //sum 1 billion to 2 billion
void sum3b(); //sum 1 to 1 billion
void sum4b(); //sum 1 billion to 2 billion

int main(){
  int status;
  pid_t pid1 = fork();

  //timer
  struct timeval start, end;
  long mtime, seconds, useconds;  
  gettimeofday(&start, NULL); //timer

  if(pid1 < 0){         //fork failed
    fprintf(stderr, "Fork Failed!");
    return 1;
  }else if(pid1 == 0){  //child process
    pid_t pid2 = fork();
    if(pid2==0){
        pid_t pid3 = fork();
        if(pid3==0){
            sum4b();
        }else{
            sum3b();
            wait(NULL);
        }
    }else{
      sum2b();
      wait(NULL);
    }
  }else{               //parent process
    sum1b();
    wait(NULL);

    gettimeofday(&end, NULL); //timer
    //timer
    seconds  = end.tv_sec  - start.tv_sec;
    useconds = end.tv_usec - start.tv_usec;
    mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;
    printf("Elapsed time: %ld milliseconds on pid=%d\n", mtime, pid1); 
  }

  return 0;
}

void sum1b(){
  long sum =0;
  for(int i=1;i<500000000;i++){
    sum += i;
  }
  printf("The sum of 1 to 0.5b is: %ld\n", sum);
}

void sum2b(){
  long sum =0;
  for(int i=500000000;i<1000000000;i++){
    sum += i;
  }
  printf("The sum of 0.5b to 1b is: %ld\n", sum);
}
void sum3b(){
  long sum =0;
  for(int i=1000000000;i<1500000000;i++){
    sum += i;
  }
  printf("The sum of 1 to 1.5b is: %ld\n", sum);
}

void sum4b(){
  long sum =0;
  for(int i=1500000000;i<2000000000;i++){
    sum += i;
  }
  printf("The sum of 1.5b to 2b is: %ld\n", sum);
}

如何将每个结果添加到共享内存空间,然后让父结果收集所有部分结果并返回最终结果?

1 个答案:

答案 0 :(得分:0)

您可以使用mmap分配共享内存,

long *array;
array=(long *)mmap(NULL, sizeof(long)*4, PROT_READ|PROT_WRITE,
                   MAP_SHARED|MAP_ANONYMOUS, -1, 0);

修改后的代码如下:

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/mman.h>

void sum1b(long *psum); //sum 1 to 1 billion
void sum2b(long *psum); //sum 1 billion to 2 billion
void sum3b(long *psum); //sum 1 to 1 billion
void sum4b(long *psum); //sum 1 billion to 2 billion

int main()
{
    int status, i;
    long sum = 0;
    long *array;

    //timer
    struct timeval start, end;
    long mtime, seconds, useconds;

    gettimeofday(&start, NULL); //timer
    array=(long *)mmap(NULL, sizeof(long)*4, PROT_READ|PROT_WRITE,
                        MAP_SHARED|MAP_ANONYMOUS, -1, 0);
    pid_t pid1 = fork();

    if(pid1 < 0) {        //fork failed
        fprintf(stderr, "Fork Failed!");
        return 1;
    } else if(pid1 == 0) { //child process
        pid_t pid2 = fork();
        if(pid2==0) {
            pid_t pid3 = fork();
            if(pid3==0) {
                sum4b(array);
            } else {
                sum3b(array);
                wait(NULL);
            }
        } else {
            sum2b(array);
            wait(NULL);
        }
    } else {              //parent process
        sum1b(array);
        wait(NULL);

        for(i=0; i<4; i++) {
            printf("array[%d]=%ld\n", i, array[i]);
            sum += array[i];
        }

        gettimeofday(&end, NULL); //timer
        //timer
        seconds  = end.tv_sec  - start.tv_sec;
        useconds = end.tv_usec - start.tv_usec;
        mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;
        printf("Elapsed time: %ld milliseconds on pid=%d sum=%ld\n", mtime, pid1, sum);

        munmap(array, sizeof(long)*4);
    }

    return 0;
}

void sum1b(long *psum)
{
    long sum =0;
    for(int i=1; i<500000000; i++) {
        sum += i;
    }
    psum[0] = sum;
    printf("The sum of 1 to 0.5b is: %ld\n", sum);
}

void sum2b(long *psum)
{
    long sum =0;
    for(int i=500000000; i<1000000000; i++) {
        sum += i;
    }
    psum[1] = sum;
    printf("The sum of 0.5b to 1b is: %ld\n", sum);
}

void sum3b(long *psum)
{
    long sum =0;
    for(int i=1000000000; i<1500000000; i++) {
        sum += i;
    }
    psum[2] = sum;
    printf("The sum of 1b to 1.5b is: %ld\n", sum);
}

void sum4b(long *psum)
{
    long sum =0;
    for(int i=1500000000; i<2000000000; i++) {
        sum += i;
    }
    psum[3] = sum;
    printf("The sum of 1.5b to 2b is: %ld\n", sum);
}

但是,建议此方案使用多线程。
祝你好运!