// 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 <stdio.h>
#include <time.h>
#include <windows.h>
#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);
}