PThread并行实现矩阵乘法

以下用Eclipse luna 在OS X 10.10下编译通过。


#include "MatrixMultiplication.h"

void* Hello(void* rank);

int main() {
	long thread;
	pthread_t* thread_handles;
	thread_handles = reinterpret_cast(malloc(
			thread_count * sizeof(pthread_t)));
	for (thread = 0; thread < thread_count; thread++) {
		pthread_create(&thread_handles[thread], NULL, Hello, (void*) thread);
	}
	printf("Hello world from the main thread.\n");
	for (thread = 0; thread < thread_count; thread++) {
		pthread_join(thread_handles[thread], NULL);
	}
	free(thread_handles);
	GenerateMatrix();
	printf("\nBegin to multiply two matrix...\n");
	MultiplyMatrix();

	return 0;
}

void* Hello(void* rank) {
	long my_rank = reinterpret_cast(rank);
	printf("Hello world from %ld thread of %ld.\n", my_rank, thread_count);
	return NULL;
}



#include 
#include 
#include 
#include 
#include 
#include 

#define MATRIX_COLUMN 1000
#define MATRIX_ROW 1000

using namespace std;

long thread_count = 2; //Actually, the number of the threads is thread_count square.

int matrix_a[MATRIX_ROW][MATRIX_COLUMN];
int matrix_b[MATRIX_ROW][MATRIX_COLUMN];
int serial_result_matrix[MATRIX_ROW][MATRIX_COLUMN];
int parallel_result_matrix[MATRIX_ROW][MATRIX_COLUMN];

struct thread_data {
	int row;
	int column;
};

void* Thread_Multiplication(void* data);

void MultiplyMatrix() {
	//Measure time costs.
	timeval tpstart, tpend;
	double timeuse;

	fstream file_a_stream, file_b_stream, file_serial_stream,
			file_parallel_stream;
	file_a_stream.open("a.txt", ios::in);
	file_b_stream.open("b.txt", ios::in);
	if (file_a_stream.good()) {
		cout << "Open file a successfully!" << endl;
	}
	if (file_b_stream.good()) {
		cout << "Open file b successfully!" << endl;
	}

	//long buffer_a, buffer_b;
	for (int i = 0; i < MATRIX_ROW; i++) {
		for (int j = 0; j < MATRIX_COLUMN; j++) {
			file_a_stream >> matrix_a[i][j];
			file_b_stream >> matrix_b[i][j];
		}
	}

	//Operate matrix multiplication in a serial way.
	gettimeofday(&tpstart, NULL);
	for (int i = 0; i < MATRIX_ROW; i++) {
		for (int j = 0; j < MATRIX_COLUMN; j++) {
			serial_result_matrix[i][j] = 0;
			for (int k = 0; k < MATRIX_ROW; k++) {
				serial_result_matrix[i][j] += matrix_a[i][k] * matrix_b[k][j];

			}
		}
	}
	gettimeofday(&tpend, NULL);

//	//Print the result.
//	for (int i = 0; i < MATRIX_ROW; i++) {
//		for (int j = 0; j < MATRIX_COLUMN; j++) {
//			cout << serial_result_matrix[i][j] << " ";
//		}
//		cout << endl;
//	}
	timeuse = (tpend.tv_sec - tpstart.tv_sec)
			+ (tpend.tv_usec - tpstart.tv_usec) / 1000000.0;
	//Store the serial result matrix in a file.
	file_serial_stream.open("SerialResultMatrix.txt", ios::out);
	for (int i = 0; i < MATRIX_ROW; i++) {
		for (int j = 0; j < MATRIX_COLUMN; j++) {
			file_serial_stream << serial_result_matrix[i][j] << " ";
		}
		file_serial_stream << endl;
	}

	printf("The time cost of a serial procedure:%fs\n", timeuse);

//Operate matrix multiplication in a parallel way using PThread.
	cout << "Parallel matrix multiplication begin." << endl;
	for (int i = 0; i < MATRIX_ROW; i++) {
		for (int j = 0; j < MATRIX_COLUMN; j++) {
			parallel_result_matrix[i][j] = 0;
		}
	}

//int thread_row = MATRIX_ROW / thread_count;
//int thread_column = MATRIX_COLUMN / thread_count;
	thread_data* data = reinterpret_cast(malloc(
			(thread_count * thread_count) * sizeof(thread_data)));
	pthread_t* thread_handles;
	thread_handles = reinterpret_cast(malloc(
			(thread_count * thread_count) * sizeof(pthread_t)));
	int row_counter, column_counter, thread_counter = 0;
	gettimeofday(&tpstart, NULL);
	for (row_counter = 0; row_counter < thread_count; row_counter++) {
		for (column_counter = 0; column_counter < thread_count;
				column_counter++) {
			data[thread_counter].row = row_counter;
			data[thread_counter].column = column_counter;
//			printf("From main thread: Create thread. row%d column:%d.\n",
//					data[thread_counter].row, data[thread_counter].column);
			pthread_create(&thread_handles[thread_counter], NULL,
					Thread_Multiplication, (void*) (&data[thread_counter]));
			thread_counter++;
		}
	}

	for (int i = 0; i < thread_count * thread_count; i++) {
		pthread_join(thread_handles[i], NULL);
		//cout << "Threads join the process." << endl;
	}
	gettimeofday(&tpend, NULL);
	timeuse = (tpend.tv_sec - tpstart.tv_sec)
			+ (tpend.tv_usec - tpstart.tv_usec) / 1000000.0;
	//us and s are all include.
	free(data);
	free(thread_handles);

	//Store the parallel result matrix in a file.

	file_parallel_stream.open("ParallelResultMatrix.txt", ios::out);
	for (int i = 0; i < MATRIX_ROW; i++) {
		for (int j = 0; j < MATRIX_COLUMN; j++) {
			file_parallel_stream << parallel_result_matrix[i][j] << " ";
		}
		file_parallel_stream << endl;
	}
	printf("The time cost of a parallel procedure with %ld threads:%fs\n",
			thread_count * thread_count, timeuse);

	file_parallel_stream.close();
	file_serial_stream.close();
	file_a_stream.close();
	file_b_stream.close();
}

//Generate two random matrices
void GenerateMatrix() {
	FILE * fp;
	fp = fopen("a.txt", "w");
	int n = 0, i = 0, j = 0;
	for (i = 0; i < 1000; i++) {
		for (j = 0; j < 1000; j++) {
			n = ((j + i) * 91) % 97;
			if (n == 0)
				n = 11;
			fprintf(fp, "%d ", n);
		}
		fputc('\n', fp);
	}
	fclose(fp);
	fp = fopen("b.txt", "w");
	for (i = 0; i < 1000; i++) {
		for (j = 0; j < 1000; j++) {
			n = ((j + i) * 97) % 99;
			if (n == 0)
				n = 13;
			fprintf(fp, "%d ", n);
		}
		fputc('\n', fp);
	}
	fclose(fp);
	printf("Matrix generated successfully!\n");
}

//Function operated by every thread.
void* Thread_Multiplication(void* data) {
	thread_data* my_thread_data = reinterpret_cast(data);

	int local_row = MATRIX_ROW / thread_count;
	int local_column = MATRIX_COLUMN / thread_count;

	int my_first_row = my_thread_data->row * local_row;
	int my_last_row = my_first_row + local_row;

	int my_first_column = my_thread_data->column * local_column;
	int my_last_column = my_first_column + local_column;

	//printf("Create thread. row%d column:%d.\n", my_first_row, my_first_column);
	int sum;
	for (int i = my_first_row; i < my_last_row; i++) {
		for (int j = my_first_column; j < my_last_column; j++) {
			//parallel_result_matrix[i][j] = 0;
			sum = 0;
			for (int k = 0; k < MATRIX_ROW; k++) {
				sum+= matrix_a[i][k] * matrix_b[k][j];
				//printf("%d\n", parallel_result_matrix[i][j]);
			}
			parallel_result_matrix[i][j] = sum;
		}
	}
	return 0;
}


你可能感兴趣的:(Computing)