【高性能计算】水桶问题C/C++实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}

可以看到,下面用多个核来做测试结果都是一致的。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/a19990412/article/details/83511222