並行計算 利用openmpi實現雅可比迭代法

雅克比迭代法:

這個方法是用來解線性方程的,即給定係數矩陣AA和右邊的列向量BB,求滿足AX=BA*X=B的列向量XX。此處不講原理,只給出實現方法。
輸入:係數矩陣AA(保證AA是嚴格對角佔優的)和列向量BB
輸出:列向量XX
環境:VS2019VS2019
tipstips:雖然結果是正確的,但是感覺加速比特別低…有懂的大佬可以探討一下。
codecode:

#include<omp.h>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<vector>
#include<ctime>
#include<cmath>
#include<algorithm>
#define NUM_THREADS 16	//線程個數
#define eps 1e-6	//精度
using namespace std;

const int n = 10000;	//矩陣大小

double matrix[n][n];	//係數矩陣
double x[n];	//待求解
double y[n];	//臨時存儲結果
double b[n];	//matrix * x = b

void init()		//注意 係數矩陣A要生成嚴格對角佔優的 這樣才能保證雅克比迭代法的收斂性
{
	srand(time(0));
	double sum = 0;
	for (int i = 0; i < n; i++)
	{
		sum = 0;
		for (int j = 0; j < n; j++)
		{
			if (j == i)
				continue;
			matrix[i][j] = rand() % 10 - 5;
			sum += abs(matrix[i][j]);
		}
		if (rand() & 1)		//嚴格對角佔優
			matrix[i][i] = sum + 1;
		else
			matrix[i][i] = -sum - 1;
	}
	for (int i = 0; i < n; i++)
	{
		b[i] = rand() % 10 - 5;
		x[i] = 0;
	}
}

int main()
{
	omp_set_num_threads(NUM_THREADS);

	clock_t start = clock();

	init();
	int rownum = n / NUM_THREADS;	//每個線程處理的行數
	rownum = max(rownum, 1);
	int myid;	//線程id
	double Max = 0;
	#pragma omp parallel 
	{
		myid = omp_get_thread_num();	//線程id
		int rowmin = myid * rownum;		//該線程需要計算的行的起點
		int rowmax = rowmin + rownum;
		rowmax = min(rowmax, n);
		if (myid == NUM_THREADS - 1)
			rowmax = n;
		double sum = 0;
		for(;;)
		{
			Max = 0;
			for (int i = rowmin; i < rowmax; i++)
			{
				sum = b[i];
				for (int j = 0; j < n; j++)
				{
					if (j == i)
						continue;
					sum -= matrix[i][j] * x[j];
				}
				y[i] = sum / matrix[i][i];
				Max = max(Max, abs(y[i] - x[i]));	//記錄最大差距值
			}
			#pragma omp single
			{
				memcpy(x, y, sizeof(x));
			}
			if (Max <= eps)
				break;
			#pragma omp barrier
			{

			}
			/*cout << Max << endl;*/
		}
	}

	clock_t end = clock();
	//cout << "係數矩陣爲:\n";
	//for (int i = 0; i < n; i++)
	//{
	//	for (int j = 0; j < n; j++)
	//		printf("%-5.0f", matrix[i][j]);
	//	printf("\n");
	//}
	//cout << "\n向量爲:\n";
	//for (int i = 0; i < n; i++)
	//	printf("%.0f\n", b[i]);
	//cout << "\n結果爲:\n";
	//for (int i = 0; i < n; i++)
	//	printf("%.4f\n", x[i]);
	//cout << "\n";
	cout << NUM_THREADS << "個線程耗時: " << end - start << "\n";
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章