Sie sind auf Seite 1von 9

Uji kecepatan perkalian Matriks dengan menggunakan Algoritma Standar dan Algoritma

Strassen
Program di kerjakan pada Laptop Toshiba Satellite L635, Processor Intel Core i3 M370 2,4 GHz
32-bit operation, serta menggunakan Compiler Dev-c++
Listing Program Algoritma Standar (Nave) dan Algoritma Strassen
#include <iostream>
#include <stdlib.h>
#include <stdio.h>

void mmult(int N,
int Xpitch, const double X[],
int Ypitch, const double Y[],
int Zpitch, double Z[])
{
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
{
double sum = 0.0;
for (int k = 0; k < N; k++)
sum += X[i*Xpitch + k]*Y[k*Ypitch + j];
Z[i*Zpitch + j] = sum;
}
}

// S = X + Y

void madd(int N,
int Xpitch, const double X[],
int Ypitch, const double Y[],

int Spitch, double S[])


{
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
S[i*Spitch + j] = X[i*Xpitch + j] + Y[i*Ypitch + j];
}

// S = X - Y

void msub(int N,
int Xpitch, const double X[],
int Ypitch, const double Y[],
int Spitch, double S[])
{
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
S[i*Spitch + j] = X[i*Xpitch + j] - Y[i*Ypitch + j];
}

// Perkalian Matriks dengan menggunakan ALgoritma Strassen


void mmult_fast(int N,
int Xpitch, const double X[],
int Ypitch, const double Y[],
int Zpitch, double Z[]) {

// Jika matriks yang digunakan adalah 20x20


// maka kita hanya akan menggunakan perkalian matriks dengan menngunakan
//Algoritma standar

if (N <= 20)
{
mmult(N, Xpitch, X, Ypitch, Y, Zpitch, Z);
return;
}

const int n = N/2;

const double *A = X;
const double *B = X + n;
const double *C = X + n*Xpitch;
const double *D = C + n;

const double *E = Y;
const double *F = Y + n;
const double *G = Y + n*Ypitch;
const double *H = G + n;

double *P[7];
const int sz = n*n*sizeof(double);
for (int i = 0; i < 7; i++)
P[i] = (double *) malloc(sz);
double *T = (double *) malloc(sz);
double *U = (double *) malloc(sz);

// P0 = A*(F - H);
msub(n, Ypitch, F, Ypitch, H, n, T);

mmult_fast(n, Xpitch, A, n, T, n, P[0]);

// P1 = (A + B)*H
madd(n, Xpitch, A, Xpitch, B, n, T);
mmult_fast(n, n, T, Ypitch, H, n, P[1]);

// P2 = (C + D)*E
madd(n, Xpitch, C, Xpitch, D, n, T);
mmult_fast(n, n, T, Ypitch, E, n, P[2]);

// P3 = D*(G - E);
msub(n, Ypitch, G, Ypitch, E, n, T);
mmult_fast(n, Xpitch, D, n, T, n, P[3]);

// P4 = (A + D)*(E + H)
madd(n, Xpitch, A, Xpitch, D, n, T);
madd(n, Ypitch, E, Ypitch, H, n, U);
mmult_fast(n, n, T, n, U, n, P[4]);

// P5 = (B - D)*(G + H)
msub(n, Xpitch, B, Xpitch, D, n, T);
madd(n, Ypitch, G, Ypitch, H, n, U);
mmult_fast(n, n, T, n, U, n, P[5]);

// P6 = (A - C)*(E + F)
msub(n, Xpitch, A, Xpitch, C, n, T);
madd(n, Ypitch, E, Ypitch, F, n, U);
mmult_fast(n, n, T, n, U, n, P[6]);

// Baris pertama kolom 1 = (P3 + P4) + (P5 - P1)


madd(n, n, P[4], n, P[3], n, T);
msub(n, n, P[5], n, P[1], n, U);
madd(n, n, T, n, U, Zpitch, Z);

// Baris Kedua kolom 1 = P2 + P3


madd(n, n, P[2], n, P[3], Zpitch, Z + n*Zpitch);

// Baris Pertama kolom 2 = P0 + P1


madd(n, n, P[0], n, P[1], Zpitch, Z + n);

// Baris Kedua kolom 2 = (P0 + P4) - (P2 + P6)


madd(n, n, P[0], n, P[4], n, T);
madd(n, n, P[2], n, P[6], n, U);
msub(n, n, T, n, U, Zpitch, Z + n*(Zpitch + 1));

free(U);
free(T);
for (int i = 6; i >= 0; i--)
free(P[i]);
}
void mprint(int N, int pitch, const double M[])
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
printf("%+0.4f ", M[i*pitch + j]);

printf("\n");
}
}
#ifdef MM_TEST1
int main(void)
{
double X[4*4] =
{
2, 4, 2, 5,
-3, 1, 4, 2,
1, 5, 6, -2,
6, 2, 4, 2
};
double Y[4*4] =
{
5, 1, 4, 2,
2, -6, 1, 3,
4, 2, 4, 5,
1, 3, -2, 1
};
double Z[4*4];
mmult(4, 4, X, 4, Y, 4, Z);
mprint(4, 4, Z);
printf("=========\n");

double Zfast[4*4];
mmult_fast(4, 4, X, 4, Y, 4, Zfast);
mprint(4, 4, Zfast);

return 0;
}

#endif

void mrand(int N, int pitch, double M[])


{
const double r = 10.0;
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
M[i*pitch + j] = r*(2*rand() - 1);
}

#include <sys/time.h>

int timeval_subtract(struct timeval *result,


struct timeval *t2, struct timeval *t1)
{
long int diff =
(t2->tv_usec + 1000000 * t2->tv_sec) (t1->tv_usec + 1000000 * t1->tv_sec);
result->tv_sec = diff / 1000000;
result->tv_usec = diff % 1000000;
return (diff<0);
}

void timeval_print(struct timeval *tv) {

char buffer[30];
time_t curtime;

/*printf("%ld.%06ld", (long int) tv->tv_sec, (long int) tv->tv_usec);


curtime = tv->tv_sec;
strftime(buffer, 30, "%m-%d-%Y %T", localtime(&curtime));
printf(" = %s.%06ld\n", buffer, (long int) tv->tv_usec);*/
}

#define N 1000

int main(void)
{
double *X, *Y, *Z, *Zfast;
X = (double*) malloc(N*N*sizeof(double));
Y = (double*) malloc(N*N*sizeof(double));
Z = (double*) malloc(N*N*sizeof(double));
Zfast = (double*) malloc(N*N*sizeof(double));

mrand(N, N, X);
mrand(N, N, Y);
mrand(N, N, Z);
mrand(N, N, Zfast);

struct timeval tvBegin, tvEnd, tvDiff;

gettimeofday(&tvBegin, NULL);
timeval_print(&tvBegin);

mmult(N, N, X, N, Y, N, Z);
gettimeofday(&tvEnd, NULL);
timeval_print(&tvEnd);
timeval_subtract(&tvDiff, &tvEnd, &tvBegin);
printf("%ld.%06ld\n", (long int) tvDiff.tv_sec, (long int) tvDiff.tv_usec);

gettimeofday(&tvBegin, NULL);
timeval_print(&tvBegin);
mmult_fast(N, N, X, N, Y, N, Zfast);
gettimeofday(&tvEnd, NULL);
timeval_print(&tvEnd);
timeval_subtract(&tvDiff, &tvEnd, &tvBegin);
printf("%ld.%06ld\n", (long int) tvDiff.tv_sec, (long int) tvDiff.tv_usec);

return 0;
}

Das könnte Ihnen auch gefallen