运用MPI并行实现归并排序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37717751/article/details/81050306

       比较可惜的是没有用到树形结构,仅仅是在线程中进行计算后全部在0号进程中合并

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

#define MAX_SIZE 10000

void Merge(int* a, int* b,int start, int middle, int end)
{
    int na1, na2, nb, i;
    na1 = start;
    nb = start;
    na2 = middle + 1;

    while ((na1 <= middle) && (na2 <= end)) {
        if (a[na1] <= a[na2]) {
            b[nb++] = a[na1++];
        } else {
            b[nb++] = a[na2++];
        }
    }

    if (na1 <= middle) {
        for (i = na1; i <= middle; i++) {
            b[nb++] = a[i];
        }
    }
    if (na2 <= end) {
        for (i = na2; i <= end; i++) {
            b[nb++] = a[i];
        }
    }

    for (i = start; i <= end; i++) {
        a[i] = b[i];
    }
}

void Merge_Sort(int* a, int* b, int start, int end)
{
    int middle;
    
    if (start < end) {
        middle = (start + end) / 2;
        Merge_Sort(a, b, start, middle);
        Merge_Sort(a, b, middle + 1, end);
        Merge(a, b, start, middle, end);
    }
}

int main(int argc,char *argv[])
{
    int arr[MAX_SIZE];
    int comm_sz;
    int my_rank;
    int length = 0;
    int size;
    int* sub;
    int* tmp;
    int* result = NULL;
    int * tmp_for_last;
    int i;
    FILE* fpread;
 
    // 读文件
    for (i = 0; i < MAX_SIZE; i++) {
        arr[i] = -9999;
    }

    fpread = fopen(argv[1], "r");
    if (fpread == NULL) {  
	    printf("Read error!");        
	    return 0;  
    }
    for (i = 0; !feof(fpread); i++) {
        fscanf(fpread, "%d ", &arr[i]);
        length++;
    }

    MPI_Init(NULL, NULL);
    MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

    size = length / comm_sz;  // 计算每个进程所需数组的大小
    sub = (int *)malloc(size * sizeof(int));  // 为进程所用数组开辟空间

    MPI_Scatter(arr, size, MPI_INT, sub, size, MPI_INT, 0, MPI_COMM_WORLD);  // 将数组元素分发给每个进程

    tmp = (int *)malloc(size * sizeof(int));  // 开辟归并排序时需要的临时数组
    Merge_Sort(sub, tmp, 0, size - 1);

    if(my_rank == 0) {
        result = (int *)malloc(length * sizeof(int));  // 开辟结果所需的数组空间(与输入数组一样大)
    }

    MPI_Gather(sub, size, MPI_INT, result, size, MPI_INT, 0, MPI_COMM_WORLD);  // 将各进程排序的数组收集到0号进程

    if (my_rank == 0) {
        tmp_for_last = malloc(length * sizeof(int));
        Merge_Sort(result, tmp_for_last, 0, length - 1);

        // 打印结果
        printf("\nThe result is: \n");
        for (i = 0; i < length; i++) {
            printf("%d ", result[i]);
        }
        printf("\n");

        free(result);
        free(tmp_for_last);
    }
    free(sub);
    free(tmp);
    
    MPI_Finalize();
    return 0;
}

在Linux环境下,使用以下命令生成可执行文件

mpicc -g -Wall -o 文件名 文件名.c

测试命令

mpiexec -n 9 ./文件名 input.txt

猜你喜欢

转载自blog.csdn.net/m0_37717751/article/details/81050306
今日推荐