版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a19990412/article/details/83511222
简述
就是用不同的水桶,来统计落入在各个水桶中的数量。
其实就是用数值来表示的。
实例输入数据:input.txt文件
数据解释:
- 第一行表示的是数据数量
- 第二行的是数据
- 第三行的是水桶最小值和最大值
- 第四行的是水桶的数量
20
1.3 2.9 0.4 0.3 1.3 4.4 1.7 0.4 3.2 0.3 4.9 2.4 3.1 4.4 3.9 0.4 4.2 4.5 4.9 0.9
0 5
5
实例输出:
6 3 2 3 6
请按任意键继续. . .
串行版本
#include <stdio.h>
#include <mpi.h>
#include <windows.h>
#include <iostream>
using namespace std;
#include <fstream>
int Find_bin(double x, double *bin_maxes, int bin_count, double min_meas) {
for (int i = 0; i < bin_count; ++i) {
if (x < bin_maxes[i]) return i;
}
return bin_count; // 越界
}
int main(int argc, char *argv[])
{
ifstream cin("input.txt");
int data_count, bin_count;
cin >> data_count;
double *data = new double[data_count];
double min_meas, max_meas;
for (int i = 0; i < data_count; ++i) cin >> data[i];
cin >> min_meas >> max_meas;
cin >> bin_count;
// bin_count:水桶数目
// bin_counts:各水桶的数组
// bin_maxes:各水桶的最大值
double *bin_maxes = new double[bin_count];
int* bin_counts = new int[bin_count];
double bin_width = (max_meas - min_meas) / bin_count;
for (int i = 0; i < bin_count; ++i){
bin_maxes[i] = min_meas + bin_width * (i + 1);
bin_counts[i] = 0;
}
int bin;
for (int i = 0; i < data_count; ++i) {
bin = Find_bin(data[i], bin_maxes, bin_count, min_meas);
bin_counts[bin] ++;
}
for (int i = 0; i < bin_count; ++i) { cout << bin_counts[i] << " "; }
cout << endl;
delete[] bin_counts;
delete[] bin_maxes;
delete[] data;
system("pause");
return 0;
}
MPI并行版本
#include<stdio.h>
#include<string.h>
#include<mpi.h>
#pragma warning(disable : 4996)
#define MAX_STRING 100
using namespace std;
#include <fstream>
#include <iostream>
int Find_bin(double x, double *bin_maxes, int bin_count) {
for (int i = 0; i < bin_count; ++i) {
if (x < bin_maxes[i]) return i;
}
return bin_count; // 越界
}
int main(void) {
int comm_sz;
int my_rank;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
// 只有一个线程的时候不操作
if (comm_sz <= 1) {
MPI_Finalize();
return 0;
}
if (my_rank == 0) {
ifstream cin("D:\\C++\\VS\\repo\\MPI-DEMO\\MPI-DEMO\\input.txt");
int data_count, bin_count;
cin >> data_count;
double *data = new double[data_count];
for (int i = 0; i < data_count; ++i)cin >> data[i];
double min_meas, max_meas;
cin >> min_meas >> max_meas >> bin_count;
double *bin_maxes = new double[bin_count];
int *bin_counts = new int[bin_count];
double bin_width = (max_meas - min_meas) / bin_count;
for (int i = 0; i < bin_count; ++i) {
bin_maxes[i] = min_meas + bin_width * (i + 1);
bin_counts[i] = 0;
}
int time_stemp[2];
// 分配任务
if (comm_sz > data_count) {
MPI_Send(&data_count, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
MPI_Send(data, data_count, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD);
time_stemp[0] = 0, time_stemp[1] = data_count - 1;
MPI_Send(time_stemp, 2, MPI_INT, 1, 0, MPI_COMM_WORLD);
// bin_count
MPI_Send(&bin_count, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
MPI_Send(&bin_maxes, bin_count, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD);
MPI_Recv(bin_counts, bin_count, MPI_INT, 1, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
}
else {
int width = data_count / (comm_sz - 1);
for (int i = 1; i < comm_sz; ++i)
{
MPI_Send(&data_count, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
time_stemp[0] = width * (i - 1);
if (i == comm_sz - 1) time_stemp[1] = data_count - 1;
else time_stemp[1] = width * i - 1;
MPI_Send(data, data_count, MPI_DOUBLE, i, 0, MPI_COMM_WORLD);
MPI_Send(time_stemp, 2, MPI_INT, i, 0, MPI_COMM_WORLD);
// bin_count
MPI_Send(&bin_count, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
MPI_Send(bin_maxes, bin_count, MPI_DOUBLE, i, 0, MPI_COMM_WORLD);
}
int * temp_bin_counts = new int[bin_count];
for (int i = 1; i < comm_sz; ++i)
{
MPI_Recv(temp_bin_counts, bin_count, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
for (int j = 0; j < bin_count; ++j) { bin_counts[j] += temp_bin_counts[j]; }
}
delete[] temp_bin_counts;
}
for (int i = 0; i < bin_count; ++i) std::cout << bin_counts[i] << " ";
std::cout << endl;
delete[] bin_counts;
delete[] bin_maxes;
delete[] data;
} // 运算的子节点
else {
int data_count, bin_count;
MPI_Recv(&data_count, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
double *data = new double[data_count];
MPI_Recv(data, data_count, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
int time_stemp[2];
MPI_Recv(time_stemp, 2, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&bin_count, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
double *bin_maxes = new double[bin_count];
int *bin_counts = new int[bin_count];
MPI_Recv(bin_maxes, bin_count, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
for (int i = 0; i < bin_count; ++i) bin_counts[i] = 0;
int bin;
for (int i = time_stemp[0]; i <= time_stemp[1]; ++i) {
bin = Find_bin(data[i], bin_maxes, bin_count);
bin_counts[bin] ++;
}
MPI_Send(bin_counts, bin_count, MPI_INT, 0, 0, MPI_COMM_WORLD);
delete[] data;
delete[] bin_maxes;
delete[] bin_counts;
}
MPI_Finalize();
return 0;
}
可以看到,下面用多个核来做测试结果都是一致的。