Добавление результатов параллельных процессов в общую память - PullRequest
0 голосов
/ 20 февраля 2019

В моем классе мы сейчас учимся параллельной обработке.Мы пишем на C и используем командную строку Linux.

В нашем упражнении мы добавляем сумму чисел от 0 до 2 млрд.

Пока что мы взяли серийный номерподход, где вы рассчитываете результаты 0-1 млрд. и 1-2 млрд. затем суммируйте их.

Мы также разбили эти 2 задачи на параллельный подход, сократив вдвое время выполнения.

Затем мы разбили его на 4 процесса (наши машины в классе имеют 4 ядра), каждый из которых добавил 1/42 миллиарда, затем родительская функция суммирует их все вместе, что снова вдвое сокращает время выполненияЭтот код на языке 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 голосов
/ 20 февраля 2019

Вы можете использовать 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);
}

Однако этот сценарий рекомендуется использоватьмногопоточность.
Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...