给以下代码添加注释:#include <stdio.h> #include <stdlib.h> #include <mpi.h> #define N 4000 #define TAG 0 void merge(int arr[], int l, int m, int r) { int i, j, k; int n1 = m - l + 1; int n2 = r - m; int L[4000], R[4000]; for (i = 0; i < n1; i++) L[i] = arr[l + i]; for (j = 0; j < n2; j++) R[j] = arr[m + 1 + j]; i = 0; j = 0; k = l; while (i < n1 && j < n2) { if (L[i] <= R[j]) { arr[k] = L[i]; i++; } else { arr[k] = R[j]; j++; } k++; } while (i < n1) { arr[k] = L[i]; i++; k++; } while (j < n2) { arr[k] = R[j]; j++; k++; } } void mergeSort(int arr[], int l, int r) { if (l < r) { int m = l + (r - l) / 2; mergeSort(arr, l, m); mergeSort(arr, m + 1, r); merge(arr, l, m, r); } } int main(int argc, char** argv) { int rank, size; int i, j, k; int A[N], B[N]; int block_size, start, end; double start_time, end_time; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); block_size = N / size; start = rank * block_size; end = start + block_size - 1; if (rank == size - 1) { end = N - 1; } if (rank == 0) { printf("Generating random array...\n"); for (i = 0; i < N; i++) { A[i] = rand() % 100000; } printf("Sorting array...\n"); } MPI_Barrier(MPI_COMM_WORLD); start_time = MPI_Wtime(); MPI_Scatter(A, block_size, MPI_INT, &B[start], block_size, MPI_INT, 0, MPI_COMM_WORLD); mergeSort(B, start, end); for (i = 0; i < size; i++) { if (rank == i) { MPI_Send(&B[start], block_size, MPI_INT, (rank + 1) % size, TAG, MPI_COMM_WORLD); } else if (rank == (i + 1) % size) { MPI_Recv(&B[start], block_size, MPI_INT, i, TAG, MPI_COMM_WORLD, &status); } } MPI_Barrier(MPI_COMM_WORLD); end_time = MPI_Wtime(); if (rank == 0) { printf("Writing result to file...\n"); FILE* fp; errno_t err; err = fopen_s(&fp, "sorted_array.txt", "w"); for (i = 0; i < N; i++) { fprintf(fp, "%d\n", B[i]); } fclose(fp); printf("Done!\n"); printf("Time used: %.6f seconds\n", end_time - start_time); } MPI_Finalize(); return 0; }
时间: 2024-01-16 21:03:10 浏览: 27
以下是代码注释:
```
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#define N 4000 // 定义数组大小为 4000
#define TAG 0 // 定义消息标识为 0
/**
* 归并排序中的合并操作
* @param arr 待排序数组
* @param l 数组左边界
* @param m 数组中间位置
* @param r 数组右边界
*/
void merge(int arr[], int l, int m, int r) {
int i, j, k;
int n1 = m - l + 1; // 计算左子数组的长度
int n2 = r - m; // 计算右子数组的长度
int L[4000], R[4000]; // 定义左右两个子数组
for (i = 0; i < n1; i++)
L[i] = arr[l + i]; // 将原数组的左半部分复制到左子数组中
for (j = 0; j < n2; j++)
R[j] = arr[m + 1 + j]; // 将原数组的右半部分复制到右子数组中
i = 0;
j = 0;
k = l;
while (i < n1 && j < n2) { // 将左右两个子数组中的元素逐个比较,将小的元素放入原数组中
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
}
else {
arr[k] = R[j];
j++;
}
k++;
}
while (i < n1) { // 将左子数组中剩余的元素放入原数组中
arr[k] = L[i];
i++;
k++;
}
while (j < n2) { // 将右子数组中剩余的元素放入原数组中
arr[k] = R[j];
j++;
k++;
}
}
/**
* 归并排序
* @param arr 待排序数组
* @param l 数组左边界
* @param r 数组右边界
*/
void mergeSort(int arr[], int l, int r) {
if (l < r) { // 如果数组长度大于 1,就将其分为左右两个子数组
int m = l + (r - l) / 2; // 取中间位置
mergeSort(arr, l, m); // 对左子数组进行排序
mergeSort(arr, m + 1, r); // 对右子数组进行排序
merge(arr, l, m, r); // 合并左右两个子数组
}
}
int main(int argc, char** argv) {
int rank, size;
int i, j, k;
int A[N], B[N];
int block_size, start, end;
double start_time, end_time;
MPI_Status status;
MPI_Init(&argc, &argv); // 初始化 MPI 环境
MPI_Comm_size(MPI_COMM_WORLD, &size); // 获取进程数
MPI_Comm_rank(MPI_COMM_WORLD, &rank); // 获取当前进程的编号
block_size = N / size; // 计算每个进程处理的数组块的大小
start = rank * block_size; // 计算当前进程处理的数组块的起始位置
end = start + block_size - 1; // 计算当前进程处理的数组块的结束位置
if (rank == size - 1) { // 如果是最后一个进程,需要处理剩余的部分
end = N - 1;
}
if (rank == 0) { // 只有进程 0 才生成随机数组并输出排序前的信息
printf("Generating random array...\n");
for (i = 0; i < N; i++) {
A[i] = rand() % 100000;
}
printf("Sorting array...\n");
}
MPI_Barrier(MPI_COMM_WORLD); // 等待所有进程都准备好
start_time = MPI_Wtime(); // 记录开始时间
// 将数组 A 按照块大小分配给各个进程
MPI_Scatter(A, block_size, MPI_INT, &B[start], block_size, MPI_INT, 0, MPI_COMM_WORLD);
mergeSort(B, start, end); // 对当前进程处理的数组块进行排序
// 将排好序的数组块发送给下一个进程,并接收上一个进程发送的排好序的数组块
for (i = 0; i < size; i++) {
if (rank == i) {
MPI_Send(&B[start], block_size, MPI_INT, (rank + 1) % size, TAG, MPI_COMM_WORLD);
}
else if (rank == (i + 1) % size) {
MPI_Recv(&B[start], block_size, MPI_INT, i, TAG, MPI_COMM_WORLD, &status);
}
}
MPI_Barrier(MPI_COMM_WORLD); // 等待所有进程都完成排序
end_time = MPI_Wtime(); // 记录结束时间
if (rank == 0) { // 只有进程 0 才将排好序的数组写入文件,并输出排序后的信息
printf("Writing result to file...\n");
FILE* fp;
errno_t err;
err = fopen_s(&fp, "sorted_array.txt", "w");
for (i = 0; i < N; i++) {
fprintf(fp, "%d\n", B[i]);
}
fclose(fp);
printf("Done!\n");
printf("Time used: %.6f seconds\n", end_time - start_time);
}
MPI_Finalize(); // 结束 MPI 环境
return 0;
}
```
注释包括:
- 头文件和宏定义的含义
- 各个函数的功能和参数说明
- 每个操作的作用和用途
- MPI 相关操作的含义和作用