-
1. Data: 2011-02-02 16:47:44
Temat: Porównanie szybkości mnożenia macierzy w CPP i PASCAL
Od: Fil <f...@p...onet.pl>
Witam!
Są dwie procedury:
CPP:
void MulTab(int N, int Q, int M, double** A, double** B, double** C)
{
for (int i = 0; i < N; ++i)
for (int j = 0; j < M; ++j) {
C[i][j] = 0;
for (int k = 0; k < Q; ++k) C[i][j] += A[i][k] * B[k][j];
}
}
oraz PASCAL:
TMatrix = array of array of double;
procedure MulMatrix(N, Q, M:integer; T1, T2:TMatrix; var T3:TMatrix);
var
i, j, k:integer;
begin
for i := 0 to N-1 do
for j := 0 to M-1 do begin
T3[i, j] := 0;
for k := 0 to Q-1 do T3[i, j] := T3[i, j] + T1[i, k] * T2[k, j];
end;
end;
Kompiluję obie w BCB Builder 2010 i Delphi 2010 (odpowiednio) w trybie
"release" z włączonymi optymalizacjami i odpalam.
Dla rozmiarów N = 2000 i M = 300 mam takie czasy:
CPP time = 4,5s
PAS time = 8,2s
Czasy mierzone z wykorzystaniem QueryPerformanceCounter... i wiem, że
procedurke w PASCALu można lepiej napisać, ale nie jestem fanem PASCALa
i nie sądzę, aby ten niezbyt ładnie napisany kod usprawiedliwiał TAKĄ
różnicę w czasach. Chyba, że problem tkwi w tablicach dynamicznych PASCALA?
Czy to oznacza, że Delphi nie nadaje się do obliczeń?
Pozdrawiam,
Fil.
-
2. Data: 2011-02-02 16:53:49
Temat: Re: Porównanie szybkości mnożenia macierzy w CPP i PASCAL
Od: Tomasz Kaczanowski <kaczus@dowyciecia_poczta.onet.pl>
Fil pisze:
> Witam!
>
> Są dwie procedury:
> CPP:
> void MulTab(int N, int Q, int M, double** A, double** B, double** C)
> {
> for (int i = 0; i < N; ++i)
> for (int j = 0; j < M; ++j) {
> C[i][j] = 0;
> for (int k = 0; k < Q; ++k) C[i][j] += A[i][k] * B[k][j];
> }
> }
>
> oraz PASCAL:
> TMatrix = array of array of double;
>
> procedure MulMatrix(N, Q, M:integer; T1, T2:TMatrix; var T3:TMatrix);
> var
> i, j, k:integer;
> begin
> for i := 0 to N-1 do
> for j := 0 to M-1 do begin
> T3[i, j] := 0;
> for k := 0 to Q-1 do T3[i, j] := T3[i, j] + T1[i, k] * T2[k, j];
> end;
> end;
>
> Kompiluję obie w BCB Builder 2010 i Delphi 2010 (odpowiednio) w trybie
> "release" z włączonymi optymalizacjami i odpalam.
> Dla rozmiarów N = 2000 i M = 300 mam takie czasy:
> CPP time = 4,5s
> PAS time = 8,2s
>
> Czasy mierzone z wykorzystaniem QueryPerformanceCounter... i wiem, że
> procedurke w PASCALu można lepiej napisać, ale nie jestem fanem PASCALa
> i nie sądzę, aby ten niezbyt ładnie napisany kod usprawiedliwiał TAKĄ
> różnicę w czasach. Chyba, że problem tkwi w tablicach dynamicznych PASCALA?
>
> Czy to oznacza, że Delphi nie nadaje się do obliczeń?
Zapewne się nadaje, ogólnie jednak kompilatory Borlanda słabo
optymalizują - niezależnie od języka. Więc zależy od tego co chcemy
obliczać.
--
Kaczus
http://kaczus.republika.pl
-
3. Data: 2011-02-02 16:58:51
Temat: Re: Porównanie szybkości mnożenia macierzy w CPP i PASCAL
Od: Fil <f...@p...onet.pl>
W dniu 2011-02-02 17:53, Tomasz Kaczanowski pisze:
> Zapewne się nadaje, ogólnie jednak kompilatory Borlanda słabo
> optymalizują - niezależnie od języka. Więc zależy od tego co chcemy
> obliczać.
Jak to zależy? Obliczenia to obliczenia. Zmiennoprzecinkowa arytmetyka:
dodawanie, odejmowanie, mnożenie, itd. nic wyszukanego. Na tablicach
danych - macierzach.
Co można innego liczyć, aby było szybciej? Podejrzewam jakiś myk z tymi
tablicami dynamicznymi, ale nie jestem ekspertem od PASCALA :)
Jeszcze sprawdzę na kompilatorze MS Visual C++.
Fil.
-
4. Data: 2011-02-02 17:13:03
Temat: Re: Porównanie szybkości mnożenia macierzy w CPP i PASCAL
Od: Fil <f...@p...onet.pl>
Witam jeszcze raz!
Przetestowałem jeszcze takie coś:
TA=array[0..1999,0..299] of double;
TB=array[0..299,0..1999] of double;
TC=array[0..1999,0..1999] of double;
procedure MulMatrix2(N, Q, M:integer; var T1:TA; var T2:TB; var T3:TC);
var
i, j, k:integer;
begin
for i := 0 to N-1 do
for j := 0 to M-1 do begin
T3[i, j] := 0;
for k := 0 to Q-1 do T3[i, j] := T3[i, j] + T1[i, k] * T2[k, j];
end;
end;
Czas: 5,2s
Pomijając koszmarek implementacji... czas nadal dłuższy od CPP o ok. 0.7s.
Pozdrawiam,
Fil.
-
5. Data: 2011-02-02 17:18:00
Temat: Re: Porównanie szybkości mnożenia macierzy w CPP i PASCAL
Od: Norbert <n...@r...no>
Dnia Wed, 02 Feb 2011 18:13:03 +0100, Fil napisał(a):
> Przetestowałem jeszcze takie coś:
> TA=array[0..1999,0..299] of double;
> TB=array[0..299,0..1999] of double;
> TC=array[0..1999,0..1999] of double;
>
> procedure MulMatrix2(N, Q, M:integer; var T1:TA; var T2:TB; var T3:TC);
> var
> i, j, k:integer;
> begin
> for i := 0 to N-1 do
> for j := 0 to M-1 do begin
> T3[i, j] := 0;
> for k := 0 to Q-1 do T3[i, j] := T3[i, j] + T1[i, k] * T2[k, j];
> end;
> end;
>
> Czas: 5,2s
>
> Pomijając koszmarek implementacji... czas nadal dłuższy od CPP o ok. 0.7s.
>
> Pozdrawiam,
> Fil.
Pokaz caly program, wraz z wywolywaniem tej procedury.
--
pozdrawiam
Norbert
-
6. Data: 2011-02-02 18:00:49
Temat: Re: Porównanie szybkości mnożenia macierzy w CPP i PASCAL
Od: Grzegorz Krukowski <r...@o...pl>
On Wed, 02 Feb 2011 17:58:51 +0100, Fil <f...@p...onet.pl>
wrote:
>W dniu 2011-02-02 17:53, Tomasz Kaczanowski pisze:
>
>> Zapewne się nadaje, ogólnie jednak kompilatory Borlanda słabo
>> optymalizują - niezależnie od języka. Więc zależy od tego co chcemy
>> obliczać.
>Jak to zależy? Obliczenia to obliczenia. Zmiennoprzecinkowa arytmetyka:
>dodawanie, odejmowanie, mnożenie, itd. nic wyszukanego. Na tablicach
>danych - macierzach.
>
>Co można innego liczyć, aby było szybciej? Podejrzewam jakiś myk z tymi
>tablicami dynamicznymi, ale nie jestem ekspertem od PASCALA :)
>
>Jeszcze sprawdzę na kompilatorze MS Visual C++.
>
>Fil.
Czy wyłączyłeś wszystkie mechanizmy kontrolne Pascala? Bo za czasów
kiedy go używałem to miał on kontrolę zakresów, przepełnień i tym
podobnych rzeczy a to potrafi spowolnić.
--
Grzegorz Krukowski
-
7. Data: 2011-02-02 18:14:28
Temat: Re: Porównanie szybkości mnożenia macierzy w CPP i PASCAL
Od: Fil <f...@p...onet.pl>
> Pokaz caly program, wraz z wywolywaniem tej procedury.
Wedle życzenia:
Wariant 1:
program test;
{$APPTYPE CONSOLE}
uses
SysUtils,
Windows;
type
TMatrix = array of array of double;
procedure NewMatrix(N, M:integer; var T:TMatrix);
begin
SetLength(T, N, M);
end;
procedure RndMatrix(N, M:integer; var T:TMatrix);
var
i, j:integer;
begin
for i := 0 to N-1 do
for j := 0 to M-1 do T[i, j] := random(N * M);
end;
procedure MulMatrix(N, Q, M:integer; T1, T2:TMatrix; var T3:TMatrix);
var
i, j, k:integer;
begin
for i := 0 to N-1 do
for j := 0 to M-1 do begin
T3[i, j] := 0;
for k := 0 to Q-1 do T3[i, j] := T3[i, j] + T1[i, k] * T2[k, j];
end;
end;
const
N = 2000;
M = 300;
var
A, B, C:TMatrix;
T1, T2, F:int64;
begin
randomize;
NewMatrix(N, M, A);
NewMatrix(M, N, B);
NewMatrix(N, N, C);
RndMatrix(N, M, A);
RndMatrix(M, N, B);
QueryPerformanceFrequency(F);
QueryPerformanceCounter(T1);
MulMatrix(N, M, N, A, B, C);
QueryPerformanceCounter(T2);
Writeln('Time = ' + FloatToStr((T2 - T1) / F));
end.
i wariant 2:
program test;
{$APPTYPE CONSOLE}
uses
SysUtils,
Windows;
type
TA=array[0..1999,0..299] of double;
TB=array[0..299,0..1999] of double;
TC=array[0..1999,0..1999] of double;
procedure RndMatrix2A(N, M:integer; var T:TA);
var
i, j:integer;
begin
for i := 0 to N-1 do
for j := 0 to M-1 do T[i, j] := random(N * M);
end;
procedure RndMatrix2B(N, M:integer; var T:TB);
var
i, j:integer;
begin
for i := 0 to N-1 do
for j := 0 to M-1 do T[i, j] := random(N * M);
end;
procedure MulMatrix2(N, Q, M:integer; var T1:TA; var T2:TB; var T3:TC);
var
i, j, k:integer;
begin
for i := 0 to N-1 do
for j := 0 to M-1 do begin
T3[i, j] := 0;
for k := 0 to Q-1 do T3[i, j] := T3[i, j] + T1[i, k] * T2[k, j];
end;
end;
const
N = 2000;
M = 300;
var
A:TA;
B:TB;
C:TC;
T1, T2, F:int64;
begin
randomize;
RndMatrix2A(N, M, A);
RndMatrix2B(M, N, B);
QueryPerformanceFrequency(F);
QueryPerformanceCounter(T1);
MulMatrix2(N, M, N, A, B, C);
QueryPerformanceCounter(T2);
Writeln('Time = ' + FloatToStr((T2 - T1) / F));
end.
Pozdrawiam,
Fil.
-
8. Data: 2011-02-02 18:14:51
Temat: Re: Porównanie szybkości mnożenia macierzy w CPP i PASCAL
Od: Fil <f...@p...onet.pl>
> Czy wyłączyłeś wszystkie mechanizmy kontrolne Pascala? Bo za czasów
> kiedy go używałem to miał on kontrolę zakresów, przepełnień i tym
> podobnych rzeczy a to potrafi spowolnić.
A gdzie to wyłączyć?
-
9. Data: 2011-02-02 18:20:19
Temat: Re: Porównanie szybkości mnożenia macierzy w CPP i PASCAL
Od: Fil <f...@p...onet.pl>
I jeszcze takie wariacje na temat :):
void MulTab2(int N, int Q, int M, double** A, double** B, double** C)
{
int _M, _Q;
double R;
double** Ai;
double** Bj;
double* Aik;
double* Bjk;
double* Cij;
while (N--) {
Ai = A++;
Bj = B;
Cij = *C++;
_M = M;
while (_M--) {
Aik = *Ai;
Bjk = *Bj++;
R = 0;
_Q = Q;
while (_Q--) R += *Aik++ * *Bjk++;
*Cij++ = R;
}
}
}
przy założeniu, że tablica B jest podana jako transponowana.
Czas = 4.0s. (N = 2000, Q = 300, M = 2000)
Eh... pewnie da się jeszcze lepiej i szybciej (pomijając specjalizowane
algorytmy mnożenia macierzy)...
Fil.
-
10. Data: 2011-02-02 18:40:30
Temat: Re: Porównanie szybkości mnożenia macierzy w CPP i PASCAL
Od: Grzegorz Krukowski <r...@o...pl>
On Wed, 02 Feb 2011 19:14:51 +0100, Fil <f...@p...onet.pl>
wrote:
>> Czy wyłączyłeś wszystkie mechanizmy kontrolne Pascala? Bo za czasów
>> kiedy go używałem to miał on kontrolę zakresów, przepełnień i tym
>> podobnych rzeczy a to potrafi spowolnić.
>
>A gdzie to wyłączyć?
Znjadź opcje kopilatora, pewno zakładka runtime lub coś podobnego, a
te opcje to:
Integer Overflow Checking,
Range Checking
--
Grzegorz Krukowski