- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - vermue
I also test the speed of the program. Using a core of an Intel Q6600 at 2.4GHz, the "random_number" intrinsics takes slightly more times than the generator you refer to (1.42904s vs 1.38997s for 100 million shoots, Knuth takes 2.05887s). The new generator is thread safe, which is not the case of "random_number".
I join a small test program if you want to play with it.
So, in a nutshell, it sounds very good. I may use it for business.
Olivier.
$cat testprngAlvo.f90
! Check equal values:
! ifort -fp-speculation=safe -i8 -r8 -c testprngAlvo.f90 -o testprngAlvo.o && ifort -O3 -i8 -r8 -c funprngAlvo.f90 -o funprngAlvo.o && ifort -o a.testprngAlvo1 testprngAlvo.o funprngAlvo.o && ./a.testprngAlvo1 0 1
! Check speed:
! ifort -O3 -i8 -r8 -c testprngAlvo.f90 -o testprngAlvo.o && ifort -O3 -i8 -r8 -c funprngAlvo.f90 -o funprngAlvo.o && ifort -o a.testprngAlvo0 testprngAlvo.o funprngAlvo.o && ./a.testprngAlvo0 0 0
! First arg is 0(Alvo) or 1 (random_number), second arg is 0 (timing) or 1 (check)
program testprngAlvo
implicit none
real :: xn, s
integer :: n
integer :: ic1, ic2, ir, im
integer :: taille = 10000000 ! 10 millions for timing
real :: secl
integer :: method
integer :: performance
real :: getprngAlvo
integer idum
integer :: i,j, nloop
double PRECISION, dimension(:), allocatable :: tab
character*32 :: chaine
method = 0
performance = 0
call get_command_argument(1, chaine)
if (len_trim(chaine) > 0) then
read(chaine, *) method
endif
call get_command_argument(2, chaine)
if (len_trim(chaine) > 0) then
read(chaine, *) performance
endif
if (performance == 0) then
call system_clock(count=ic1, count_rate=ir, count_max=im)
if (method == 0) then
s = 0.5
do n=0, taille
xn = getprngAlvo(xn,n,s)
enddo
elseif(method == 1) then
do n=0, taille
call random_number(xn)
enddo
end if
call system_clock(ic2)
if (ic2 > ic1) then
secl = real(ic2-ic1)/real(ir)
else
secl = real(ic2+(im-ic1))/real(ir)
endif
write(6, FMT='("xn=",D25.16," time is",F14.6)') xn, secl
else
ALLOCATE(tab(taille/10))
nloop = 0
s = 0.5
n = 0
do i=1, taille/10 ! one million first numbers tested for uniqueness
if (method == 0) then
n = n + 1
xn = getprngAlvo(xn,n,s)
elseif(method == 1) then
call random_number(xn)
end if
tab(i) = xn
do j=1, i-1
if (tab(j) == tab(i)) then
write(6, FMT='("Looping=",I7,2(1X,I15),2(1X,D27.17))') nloop,i, j, tab(i), tab(j)
nloop = nloop + 1
endif
end do
enddo
write(6, FMT='("Looping=",I12," method=",I2)') nloop,method
endif
end program testprngAlvo
$ cat funprngAlvo.f90
function getprngAlvo(xn,n,s) result(y)
real, intent(in) :: xn
integer, intent(in) :: n
real, intent(in) :: s
real :: y
y = (n * xn + n*s +s * xn)-int(n * xn + n*s +s * xn)
end function getprngAlvo
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - cessenat@free.fr
Olivier...
...thanks for your programe
I made some changes to speed up the algorithm (I think).
I do not now Fortran language.
Please correct me if i'm wrong.
The ideia is to put n as real, and cut some operations on the algotihm.
Teel me if this increase the speed.
! ifort -fp-speculation=safe -i8 -r8 -c testprngAlvo.f90 -o testprngAlvo.o && ifort -O3 -i8 -r8 -c funprngAlvo.f90 -o funprngAlvo.o && ifort -o a.testprngAlvo1 testprngAlvo.o funprngAlvo.o && ./a.testprngAlvo1 0 1
! Check speed:
! ifort -O3 -i8 -r8 -c testprngAlvo.f90 -o testprngAlvo.o && ifort -O3 -i8 -r8 -c funprngAlvo.f90 -o funprngAlvo.o && ifort -o a.testprngAlvo0 testprngAlvo.o funprngAlvo.o && ./a.testprngAlvo0 0 0
! First arg is 0(Alvo) or 1 (random_number), second arg is 0 (timing) or 1 (check)
program testprngAlvo
implicit none
real :: xn, s
real :: n !change here n pass to real
integer :: ic1, ic2, ir, im
integer :: taille = 10000000 ! 10 millions for timing
real :: secl
integer :: method
integer :: performance
real :: getprngAlvo
integer idum
integer :: i,j, nloop
double PRECISION, dimension(:), allocatable :: tab
character*32 :: chaine
method = 0
performance = 0
call get_command_argument(1, chaine)
if (len_trim(chaine) > 0) then
read(chaine, *) method
endif
call get_command_argument(2, chaine)
if (len_trim(chaine) > 0) then
read(chaine, *) performance
endif
if (performance == 0) then
call system_clock(count=ic1, count_rate=ir, count_max=im)
if (method == 0) then
s = 0.5
do n=0, taille
xn = getprngAlvo(xn,n,s)
enddo
elseif(method == 1) then
do n=0, taille
call random_number(xn)
enddo
end if
call system_clock(ic2)
if (ic2 > ic1) then
secl = real(ic2-ic1)/real(ir)
else
secl = real(ic2+(im-ic1))/real(ir)
endif
write(6, FMT='("xn=",D25.16," time is",F14.6)') xn, secl
else
ALLOCATE(tab(taille/10))
nloop = 0
s = 0.5
n = s ! change here n starts with the s value
do i=1, taille/10 ! one million first numbers tested for uniqueness
if (method == 0) then
n = n + 1
xn = getprngAlvo(xn,n,s)
elseif(method == 1) then
call random_number(xn)
end if
tab(i) = xn
do j=1, i-1
if (tab(j) == tab(i)) then
write(6, FMT='("Looping=",I7,2(1X,I15),2(1X,D27.17))') nloop,i, j, tab(i), tab(j)
nloop = nloop + 1
endif
end do
enddo
write(6, FMT='("Looping=",I12," method=",I2)') nloop,method
endif
end program testprngAlvo
$ cat funprngAlvo.f90
function getprngAlvo(xn,n,s) result(y)
real, intent(in) :: xn
real, intent(in) :: n !change here n pass to real
real, intent(in) :: s
real :: y
y = (n * xn +s)-int(n * xn +s) !change here
end function getprngAlvo
...thanks for your programe
I made some changes to speed up the algorithm (I think).
I do not now Fortran language.
Please correct me if i'm wrong.
The ideia is to put n as real, and cut some operations on the algotihm.
Teel me if this increase the speed.
! ifort -fp-speculation=safe -i8 -r8 -c testprngAlvo.f90 -o testprngAlvo.o && ifort -O3 -i8 -r8 -c funprngAlvo.f90 -o funprngAlvo.o && ifort -o a.testprngAlvo1 testprngAlvo.o funprngAlvo.o && ./a.testprngAlvo1 0 1
! Check speed:
! ifort -O3 -i8 -r8 -c testprngAlvo.f90 -o testprngAlvo.o && ifort -O3 -i8 -r8 -c funprngAlvo.f90 -o funprngAlvo.o && ifort -o a.testprngAlvo0 testprngAlvo.o funprngAlvo.o && ./a.testprngAlvo0 0 0
! First arg is 0(Alvo) or 1 (random_number), second arg is 0 (timing) or 1 (check)
program testprngAlvo
implicit none
real :: xn, s
real :: n !change here n pass to real
integer :: ic1, ic2, ir, im
integer :: taille = 10000000 ! 10 millions for timing
real :: secl
integer :: method
integer :: performance
real :: getprngAlvo
integer idum
integer :: i,j, nloop
double PRECISION, dimension(:), allocatable :: tab
character*32 :: chaine
method = 0
performance = 0
call get_command_argument(1, chaine)
if (len_trim(chaine) > 0) then
read(chaine, *) method
endif
call get_command_argument(2, chaine)
if (len_trim(chaine) > 0) then
read(chaine, *) performance
endif
if (performance == 0) then
call system_clock(count=ic1, count_rate=ir, count_max=im)
if (method == 0) then
s = 0.5
do n=0, taille
xn = getprngAlvo(xn,n,s)
enddo
elseif(method == 1) then
do n=0, taille
call random_number(xn)
enddo
end if
call system_clock(ic2)
if (ic2 > ic1) then
secl = real(ic2-ic1)/real(ir)
else
secl = real(ic2+(im-ic1))/real(ir)
endif
write(6, FMT='("xn=",D25.16," time is",F14.6)') xn, secl
else
ALLOCATE(tab(taille/10))
nloop = 0
s = 0.5
n = s ! change here n starts with the s value
do i=1, taille/10 ! one million first numbers tested for uniqueness
if (method == 0) then
n = n + 1
xn = getprngAlvo(xn,n,s)
elseif(method == 1) then
call random_number(xn)
end if
tab(i) = xn
do j=1, i-1
if (tab(j) == tab(i)) then
write(6, FMT='("Looping=",I7,2(1X,I15),2(1X,D27.17))') nloop,i, j, tab(i), tab(j)
nloop = nloop + 1
endif
end do
enddo
write(6, FMT='("Looping=",I12," method=",I2)') nloop,method
endif
end program testprngAlvo
$ cat funprngAlvo.f90
function getprngAlvo(xn,n,s) result(y)
real, intent(in) :: xn
real, intent(in) :: n !change here n pass to real
real, intent(in) :: s
real :: y
y = (n * xn +s)-int(n * xn +s) !change here
end function getprngAlvo
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would not alter the program semantics just for speed increase.
The original program seems fast enough anyway.
If you do really need speed, I would suggest you use the MKL library made by Intel that is supposed to be very fast for getting a vector of random numbers.
Sincerely,
Olivier Cessenat.
The original program seems fast enough anyway.
If you do really need speed, I would suggest you use the MKL library made by Intel that is supposed to be very fast for getting a vector of random numbers.
Sincerely,
Olivier Cessenat.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page