-
31. Data: 2012-03-02 14:49:39
Temat: Re: OpenMP - jest szybciej czy wolniej?
Od: "slawek" <s...@h...pl>
Użytkownik "Edek Pienkowski" <e...@g...com> napisał w
wiadomości grup dyskusyjnych:jiqijf$dvn$1...@i...gazeta.pl...
> Przekształcenia pętli w 3.3 to nie to samo, co w 4.6. Powiedziałbym nawet,
> że dzielą je lata świetlne.
Zgoda - tj. nie dosłownie ly, raczej zwykłe years.
-
32. Data: 2012-03-02 15:57:50
Temat: Re: OpenMP - jest szybciej czy wolniej?
Od: Edek Pienkowski <e...@g...com>
Dnia Fri, 02 Mar 2012 15:48:14 +0100, slawek napisal:
> Użytkownik "Edek Pienkowski" <e...@g...com> napisał w
> wiadomości grup dyskusyjnych:jiqi0e$dvn$1...@i...gazeta.pl...
>>> Pogrupuj po 64 i spróbuj:
>>>
>>> schedule(dynamic, 64)
>
> Nie pomogło: ani dynamic, ani static. Ani 64, ani 1, ani 1000 .
A 1/nthreads rozmiaru? Poza tym nie wiem, jaki jest model fortranu,
jak są obsługiwane shared.
A gdybyś ręcznie zrobił z tego dwie pętle:
for i = 0 ; i < n; i+= 1000
for j = i * 1000; j < i*1000 + 1000 && j < n; j++
...i zwrównoleglał na zewnętrznej z j private?
>
>> ... bo inaczej zostawiasz decyzje gcc i/lub openMP, a jednocześnie
>> używasz:
>>
>> -floop-parallelize-all
>
> Sprawdzałem też z "gołym" wywołaniem gfortran bez jakichkolwiek opcji.
Już się ktoś pytał: to na pewno ta pętla? Zmieniałeś jej rozmiar?
Edek
-
33. Data: 2012-03-02 16:00:44
Temat: Re: OpenMP - jest szybciej czy wolniej?
Od: Edek Pienkowski <e...@g...com>
Dnia Fri, 02 Mar 2012 15:57:50 +0000, Edek Pienkowski napisal:
> Dnia Fri, 02 Mar 2012 15:48:14 +0100, slawek napisal:
>
>> Użytkownik "Edek Pienkowski" <e...@g...com> napisał w
>> wiadomości grup dyskusyjnych:jiqi0e$dvn$1...@i...gazeta.pl...
>>>> Pogrupuj po 64 i spróbuj:
>>>>
>>>> schedule(dynamic, 64)
>>
>> Nie pomogło: ani dynamic, ani static. Ani 64, ani 1, ani 1000 .
>
> A 1/nthreads rozmiaru? Poza tym nie wiem, jaki jest model fortranu,
> jak są obsługiwane shared.
>
> A gdybyś ręcznie zrobił z tego dwie pętle:
>
> for i = 0 ; i < n; i+= 1000
> for j = i * 1000; j < i*1000 + 1000 && j < n; j++
j = i ; j < i+1000 && j < n ; j++
Sorry za głupi błąd.
Edek
-
34. Data: 2012-03-02 16:24:02
Temat: Re: OpenMP - jest szybciej czy wolniej?
Od: "slawek" <s...@h...pl>
Użytkownik "Paweł Kierski" <n...@p...net> napisał w wiadomości grup
dyskusyjnych:jiqgak$2sv$...@i...gazeta.pl...
> Zredukuj program do samej pętli zawierające b(i) = a(i)+a(i), puść
> w obu wersjach. Jeśli wyeliminujesz _wszystko_ inne, a problem będzie
> nadal, to można podejrzewać implementację OpenMP, system itp. Bez
Wyniki, w sekundach, są takie jak niżej. Program taki jak jeszcze niżej.
gfortran -Ofast test-omp.f95 CPU_TIME = 0.20312500
gfortran test-omp.f95 CPU_TIME = 1.9062500
gfortran -fopenmp test-omp.f95 CPU_TIME = 7.0000000
gfortran -Ofast -fopenmp .... CPU_TIME = 1.0625000 - jeżeli
wątki tworzy się tylko raz (tj. $omp parallel obejmuje CAŁY program)
Co widać? Że fast-math jest szybka, a nawet bardzo szybka - daje "10-krotne
przyspieszenie". Natomiast OpenMP
sucks - wykonanie programu jest ponad 3 razy wolniejsze do "zwykłego" - i
prawie aż 35 razy wolniejsze niż z fast-math!
Jak mi się to przekłada? Prawdziwy program (nie test) działał przez około 10
dni na 16 CPU. Fast math daje efekt
jakby procesorów było 160. Natomiast z OpenMP liczyłoby się to około 1 rok.
Nie chce mi się przekładać tego na C/C++, bo intensywnie (tzn. prawdziwy
program) używa liczb zespolonych itd.
Jednak ciekawe będzie sprawdzić, jak to wyjdzie w MSVC (wersje od
Professional wzwyż mają OpenMP). Ewentualnie
p...ć OpenMP i użyć API Windows (_beginthread() i okolice). Ewentualnie
zrobić dobry użytek z GPU.
!***************************************************
****************************************************
************************
!
! Program test-omp - powinno skompilowac sie kazdym kompilatorem Fortranu 95
!
!***************************************************
****************************************************
************************
module main
! stale matematyczne i fizyczne (CODATA 2006)
real*8, parameter :: pi =
3.14159265358979323846264338327950288419716939938D0 ! pi
real*8, parameter :: epsilon0 =
8.85418781762038985053656303171075026060837016660D-1
2 ! przenikalnosc
elektryczna prozni [F/m]
real*8, parameter :: c = 299792458.0D0
! predkosc swiatla [m/s]
integer :: n,m;
! I/O units
integer :: input = 11 ! tekstowy wejsciowy plik z danymi
integer :: output = 12 ! tekstowy wyjsciowy plik z danymi
contains
subroutine setup(vec)
implicit none
complex*16, intent(out) :: vec(:)
integer :: i
do i = 1,n
vec(i) = pi*c*epsilon0;
enddo
end subroutine setup
subroutine solve(v1,v2)
implicit none
complex*16, intent(in) :: v1(:)
complex*16, intent(out) :: v2(:)
integer :: i
!$omp parallel
!$omp do schedule(static,100)
do i = 1,n
v2(i) = v1(i)/c**2 + abs(epsilon0) + pi
enddo
!$omp end do
!$omp end parallel
end subroutine solve
end module main
program testomp
use main
implicit none
real*4 stamp0 ! pomiar czasu - stempel 0
real*4 stamp1 ! pomiar czasu - stemper 1
integer, parameter :: nmax = 10000 ! takie duze tablice sa
complex*16 :: vec(nmax,2)
integer :: i1,i2,i,j
complex*16 :: sum
call cpu_time(stamp0)
n = 1000
m = 100000
if(n.le.nmax) then
i1 = 1
i2 = 2
call setup(vec(:,i1))
do j = 1,m
call solve(vec(:,i1),vec(:,i2))
i1 = mod(i1,2) + 1
i2 = mod(i2,2) + 1
enddo
else
write(*,*) 'error: dimension(s)'
endif
call cpu_time(stamp1)
write(*,*) 'CPU time = ', stamp1-stamp0
sum = 0.D0
do i = 1,n
sum = sum + 1.D0/(1.D0+vec(i,i1)*vec(i,i1))
enddo
write(*,*) 'just for fun ', sum
end program testomp
!***************************************************
****************************************************
************************
-
35. Data: 2012-03-02 16:27:00
Temat: Re: OpenMP - jest szybciej czy wolniej?
Od: "slawek" <s...@h...pl>
Użytkownik "Edek Pienkowski" <e...@g...com> napisał w
wiadomości grup dyskusyjnych:jiqqlu$dvn$1...@i...gazeta.pl...
> Już się ktoś pytał: to na pewno ta pętla? Zmieniałeś jej rozmiar?
Wysłałem właśnie przykładowy program - są co prawda 4 pętle, ale chyba widać
o co chodzi.
!***************************************************
****************************************************
************************
!
! Program test-omp
!
!***************************************************
****************************************************
************************
module main
! stale matematyczne i fizyczne (CODATA 2006)
real*8, parameter :: pi =
3.14159265358979323846264338327950288419716939938D0 ! pi
real*8, parameter :: epsilon0 =
8.85418781762038985053656303171075026060837016660D-1
2 ! przenikalnosc
elektryczna prozni [F/m]
real*8, parameter :: c = 299792458.0D0
! predkosc swiatla [m/s]
integer :: n,m;
! I/O units
integer :: input = 11 ! tekstowy wejsciowy plik z danymi
integer :: output = 12 ! tekstowy wyjsciowy plik z danymi
contains
subroutine setup(vec)
implicit none
complex*16, intent(out) :: vec(:)
integer :: i
do i = 1,n
vec(i) = pi*c*epsilon0;
enddo
end subroutine setup
subroutine solve(v1,v2)
implicit none
complex*16, intent(in) :: v1(:)
complex*16, intent(out) :: v2(:)
integer :: i
!$omp do schedule(static,1000)
do i = 1,n
v2(i) = v1(i)/c**2 + abs(epsilon0) + pi
enddo
!$omp end do
end subroutine solve
end module main
program testomp
use main
implicit none
real*4 stamp0 ! pomiar czasu - stempel 0
real*4 stamp1 ! pomiar czasu - stemper 1
integer, parameter :: nmax = 10000 ! takie duze tablice sa
complex*16 :: vec(nmax,2)
integer :: i1,i2,i,j
complex*16 :: sum
call cpu_time(stamp0)
n = 1000
m = 100000
if(n.le.nmax) then
!$omp parallel
i1 = 1
i2 = 2
call setup(vec(:,i1))
do j = 1,m
call solve(vec(:,i1),vec(:,i2))
i1 = mod(i1,2) + 1
i2 = mod(i2,2) + 1
enddo
!$omp end parallel
else
write(*,*) 'error: dimension(s)'
endif
call cpu_time(stamp1)
write(*,*) 'CPU time = ', stamp1-stamp0
sum = 0.D0
do i = 1,n
sum = sum + 1.D0/(1.D0+vec(i,i1)*vec(i,i1))
enddo
write(*,*) 'just for fun ', sum
end program testomp
-
36. Data: 2012-03-02 16:40:09
Temat: Re: OpenMP - jest szybciej czy wolniej?
Od: Edek Pienkowski <e...@g...com>
Dnia Fri, 02 Mar 2012 17:27:00 +0100, slawek napisal:
> Użytkownik "Edek Pienkowski" <e...@g...com> napisał w
> wiadomości grup dyskusyjnych:jiqqlu$dvn$1...@i...gazeta.pl...
>> Już się ktoś pytał: to na pewno ta pętla? Zmieniałeś jej rozmiar?
>
> subroutine solve(v1,v2)
> implicit none complex*16, intent(in) :: v1(:) complex*16,
> intent(out) :: v2(:)
> integer :: i
>
> !$omp do schedule(static,1000)
> do i = 1,n
> v2(i) = v1(i)/c**2 + abs(epsilon0) + pi
> enddo !$omp end do
> end subroutine solve
>
> end module main
>
> !$omp parallel
>
> i1 = 1 i2 = 2
>
> call setup(vec(:,i1))
> do j = 1,m
> call solve(vec(:,i1),vec(:,i2))
> i1 = mod(i1,2) + 1 i2 = mod(i2,2) + 1
> enddo
> !$omp end parallel else
> write(*,*) 'error: dimension(s)'
> endif
Po co zrównoleglać dwa razy, wewnętrznie? W głównym programie to
jeszcze może mieć sens, na potrzeby testu trochę bez sensu
i możesz mieć różne konflikty na vec.
Edek
-
37. Data: 2012-03-02 16:45:38
Temat: Re: OpenMP - jest szybciej czy wolniej?
Od: Edek Pienkowski <e...@g...com>
Dnia Fri, 02 Mar 2012 16:40:09 +0000, Edek Pienkowski napisal:
> Po co zrównoleglać dwa razy, wewnętrznie? W głównym programie to jeszcze
> może mieć sens, na potrzeby testu trochę bez sensu i możesz mieć różne
> konflikty na vec.
Ignoruj... zapomniałem, co robi paralell.
-
38. Data: 2012-03-02 16:50:11
Temat: Re: OpenMP - jest szybciej czy wolniej?
Od: "slawek" <s...@h...pl>
Użytkownik "Edek Pienkowski" <e...@g...com> napisał w
wiadomości grup dyskusyjnych:jiqt59$dvn$1...@i...gazeta.pl...
> Po co zrównoleglać dwa razy, wewnętrznie? W głównym programie to
> jeszcze może mieć sens, na potrzeby testu trochę bez sensu
> i możesz mieć różne konflikty na vec.
W wariancie pierwszym było parallel wstawione na samą pętlę. W drugim jest
na cały program - czyli nie ma dwa razy - tylko w innym miejscu.
Ponieważ pętla była w pętli - to wątki były tworzone/niszczone
wielokrotnie - chciałem więc sprawdzić, co będzie, jak wątki (2 sztuki)
utworzy się tylko raz.
To że cała reszta też liczy się dwa razy - okazuje się mniejszym problemem,
niż koszt zawątkowywania-i-odwątkowywania. Śmieszne, ale prawdziwe.
-
39. Data: 2012-03-02 19:11:08
Temat: Re: OpenMP - jest szybciej czy wolniej?
Od: "slawek" <s...@h...pl>
Użytkownik "slawek" <s...@h...pl> napisał w wiadomości grup
dyskusyjnych:4f50f420$0$1231$6...@n...neostrada
.pl...
> Wyniki, w sekundach, są takie jak niżej. Program taki jak jeszcze niżej.
>
> gfortran -Ofast test-omp.f95 CPU_TIME = 0.20312500
> gfortran test-omp.f95 CPU_TIME = 1.9062500
> gfortran -fopenmp test-omp.f95 CPU_TIME = 7.0000000
> gfortran -Ofast -fopenmp .... CPU_TIME = 1.0625000 - jeżeli
> wątki tworzy się tylko raz (tj. $omp parallel obejmuje CAŁY program)
Po przeniesieniu do C i kompilacji MSVC 2010 jest nieco lepiej - ale i tak w
rebusie
bez OpenMP jest np. 8 sekund
z OpenMP jest 12 sekund
(Program jest trochę inny, bo nie ma complex i pętle z większą ilością
iteracji.)
/***************************************************
****************************************************
************************
!
! Program test-omp
!
! /openmp
!
****************************************************
****************************************************
***********************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// stale matematyczne i fizyczne (CODATA 2006)
const double pi = 3.14159265358979323846264338327950288419716939938;
const double epsilon0 =
8.85418781762038985053656303171075026060837016660E-1
2; // przenikalnosc
elektryczna prozni [F/m]
const double c = 299792458.0;
// predkosc swiatla [m/s]
static int n, m;
void setup(double vec[])
{
int i;
for(i = 0; i < n; i++)
vec[i] = pi*c*epsilon0;
}
void solve(double v1[], double v2[])
{
int i;
#pragma omp parallel
{
#pragma omp for schedule(static,100)
for(i = 0; i < n; i++)
v2[i] = v1[i]/(c*c) + epsilon0 + pi;
}
}
int main(void)
{
clock_t stamp0; // pomiar czasu - stempel 0
clock_t stamp1; // pomiar czasu - stempel 1
// takie duze tablice sa
# define nmax 10000
// problem - nie ma typu complex w MSVC - zamiast
complex
// będzie używany double :(
double vec[2][nmax];
int i1,i2,i,j;
double sum;
stamp0 = clock();
n = 1000;
m = 1000000;
if(n < nmax)
{
i1 = 0;
i2 = 1;
setup(vec[i1]);
for(j = 0; j < m; j++)
{
solve(vec[i1],vec[i2]);
i1 = (i1+1) % 2;
i2 = (i2+1) % 2;
}
}
else
puts("error: dimension(s)");
stamp1 = clock();
printf("CPU time = %lf\n", (double)(stamp1-stamp0)/CLOCKS_PER_SEC);
sum = 0.;
for(i = 0; i < n; i++)
sum += 1./(1.+vec[i1][i]*vec[i1][i]);
printf("just for fun %lf\n",sum);
getchar();
return 0;
}
-
40. Data: 2012-03-03 06:28:26
Temat: Re: OpenMP - jest szybciej czy wolniej?
Od: " " <f...@N...gazeta.pl>
slawek <s...@h...pl> napisał(a):
>
> UĹźytkownik "Edek Pienkowski" <e...@g...com> napisaĹ w
> wiadomoĹci grup dyskusyjnych:jiqt59$dvn$1...@i...gazeta.pl...
> > Po co zrĂłwnoleglaÄ dwa razy, wewnÄtrznie? W gĹĂłwnym programie to
> > jeszcze moĹźe mieÄ sens, na potrzeby testu trochÄ bez sensu
> > i moĹźesz mieÄ róşne konflikty na vec.
>
> W wariancie pierwszym byĹo parallel wstawione na samÄ pÄtlÄ. W drugim
jest
> na caĹy program - czyli nie ma dwa razy - tylko w innym miejscu.
>
> PoniewaĹź pÄtla byĹa w pÄtli - to wÄ tki byĹy tworzone/niszczone
> wielokrotnie - chciaĹem wiÄc sprawdziÄ, co bÄdzie, jak wÄ tki (2 sztuki)
> utworzy siÄ tylko raz.
>
> To Ĺźe caĹa reszta teĹź liczy siÄ dwa razy - okazuje siÄ mniejszym
problemem
> ,
> niĹź koszt zawÄ tkowywania-i-odwÄ tkowywania. Ĺmieszne, ale prawdziwe.
>
mz wiadomo a przynajmniej bezpieczniej jest zakladac ze koszt
owatkowienia moze byc spory, mi nie podoba sie watkowa rozrzutnosc,
- byc moze tak naprawde systemy mozna by robic zupelnie inaczej
trzebaby kiedys przemyslec podstawy wielowątkowosci
- tak naprawde zeby zobaczyc co sie dzieje trzebeby zobaczyc
i umiec zrozumiec kod schedulera i okolic w kernelu - warto
by to bylo po prostu obejrzec (zob watek jadro jadra)
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/