// classic.cpp : "Textbook" implementation of matrix multiply // Author: Paul J. Drongowski // Address: Boston Design Center // Advanced Micro Devices, Inc. // Boxborough, MA 01719 // Date: 20 October 2005 // // Copyright (c) 2005 Advanced Micro Devices, Inc. // Celem tego programu jest prezentacja pomiaru i analizy //efektywnosci programu za pomocą CodeAnalyst(tm). // Implementacja mnożenia macierzy jest realizowana za pomoca typowego // algorytmu podręcznikowego. // Efektywność tego podejscia jest niska poprzez // nieefektywną kolejnosć odwołań do elementów macierzy. #include #include #include #include "omp.h" #define USE_MULTIPLE_THREADS true #define MAXTHREADS 128 int NumThreads; double start; static const int ROWS = 10000; // liczba wierszy macierzy static const int COLUMNS = 10000; // lizba kolumn macierzy float matrix_a[ROWS][COLUMNS]; // lewy operand float matrix_b[ROWS][COLUMNS]; // prawy operand float matrix_r[ROWS][COLUMNS]; // wynik FILE *result_file; void initialize_matrices() { // zdefiniowanie zawarosci poczatkowej macierzy #pragma omp parallel for for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLUMNS; j++) { matrix_a[i][j] = (float)rand() / RAND_MAX; matrix_b[i][j] = (float)rand() / RAND_MAX; matrix_r[i][j] = 0.0; } } } void initialize_matricesZ() { // zdefiniowanie zawarosci poczatkowej macierzy #pragma omp parallel for for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLUMNS; j++) { matrix_r[i][j] = 0.0; } } } void print_result() { // wydruk wyniku for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLUMNS; j++) { fprintf(result_file, "%6.4f ", matrix_r[i][j]); } fprintf(result_file, "\n"); } } void multiply_matrices_IKJ() { // mnozenie macierzy #pragma omp parallel for for (int i = 0; i < ROWS; i++) for (int k = 0; k < COLUMNS; k++) for (int j = 0; j < COLUMNS; j++) matrix_r[i][j] += matrix_a[i][k] * matrix_b[k][j]; } void print_elapsed_time() { double elapsed; double resolution; // wyznaczenie i zapisanie czasu przetwarzania elapsed = (double)clock() / CLK_TCK; resolution = 1.0 / CLK_TCK; fprintf(result_file, "Czas wykonania programu: %8.4f sec (%6.4f sec rozdzielczosc pomiaru)\n", elapsed - start, resolution); } int main(int argc, char* argv[]) { // start = (double) clock() / CLK_TCK ; if ((result_file = fopen("classic.txt", "w")) == NULL) { fprintf(stderr, "nie mozna otworzyc pliku wyniku \n"); perror("classic"); return(EXIT_FAILURE); } //Determine the number of threads to use if (USE_MULTIPLE_THREADS) { SYSTEM_INFO SysInfo; GetSystemInfo(&SysInfo); NumThreads = SysInfo.dwNumberOfProcessors; if (NumThreads > MAXTHREADS) NumThreads = MAXTHREADS; } else NumThreads = 1; fprintf(result_file, "Klasyczny algorytm mnozenia macierzy, liczba watkow %d \n", NumThreads); printf("liczba watkow = %d\n\n", NumThreads); initialize_matrices(); start = (double)clock() / CLK_TCK; multiply_matrices_IKJ(); print_elapsed_time(); fclose(result_file); return(0); }