Speed difference between FB 0.16b and 0.18.3b (solved)

General FreeBASIC programming questions.
JohnB
Posts: 236
Joined: Jul 22, 2005 3:53
Location: Minnesota Arizona

Speed difference between FB 0.16b and 0.18.3b (solved)

Postby JohnB » Mar 09, 2008 8:28

I have been working with Z!re's PIH demo. I did some conversions to SDL and FBPNG. My compiled program ran very slow as compared to Z!re's .exe.

I finally cut, pasted, recompiled a console only test program. I compiled my test program with FB 0.16b and FB 0.18.3b. The 0.18.3b .exe is 14 time slower than the 0.16b .exe.

My t1-t0 times were, 0.16b - 1.2538, 0.18.3b - 19.0089, AMD Sempron 2600.

I do not know what the problem is.

Help appreciated.

JohnB

test.bas


Code: Select all

'
'
' compile using fbc -s console test.bas
'
'
Const PI = 3.1415926535897932384626

Type __VECTOR__
  x As single
  y As single
  z As single
End Type

dim shared as integer LEVEL1_DETAIL, LEVEL2_DETAIL, LEVEL3_DETAIL, LEVEL4_DETAIL

LEVEL1_DETAIL = 10
LEVEL2_DETAIL = 20
LEVEL3_DETAIL = 40
LEVEL4_DETAIL = 80

declare function getHeight(byval x as integer, byval y as integer) as double
declare function interpolate(a as double, b as double, x as double) as double
declare function noise(x as integer, y as integer) as double
declare function SmoothedNoise(x as integer, y as integer) as double
declare function InterpolatedNoise1(x as integer, y as integer) as double
declare function InterpolatedNoise2(x as integer, y as integer) as double
declare function InterpolatedNoise3(x as integer, y as integer) as double
declare function InterpolatedNoise4(x as integer, y as integer) as double

dim shared as integer fw, fh

fw = 256
fh = 256

function getHeight(byval x as integer, byval y as integer) as double
   dim as double h
   x=abs(x)
   y=abs(y)
   h = tan(InterpolatedNoise1(x, y) * 1.000 + _
         InterpolatedNoise2(x, y) * 0.500 + _
         InterpolatedNoise3(x, y) * 0.250 + _
         InterpolatedNoise4(x, y) * 0.125)
   h += 0.5
   h = 3 * h^2 - 2 * h^3
   return h
end function

function interpolate(a as double, b as double, x as double) as double       
   dim as double ft, f
   ft = x * PI
   f = (1 - cos(ft)) * .5
   return  a*(1-f) + b*f
end function

function noise(x as integer, y as integer) as double
   if x>-1 and y>-1 then
      randomize 1+x*y+sin(x)*128+cos(y)*128
      return rnd * 2 - 1
   else
      return 0
   end if
end function

function SmoothedNoise(x as integer, y as integer) as double
   dim as double corners, sides, center
   corners = ( noise(x-1, y-1)+noise(x+1, y-1)+noise(x-1, y+1)+noise(x+1, y+1) ) / 16
   sides   = ( noise(x-1, y)  +noise(x+1, y)  +noise(x, y-1)  +noise(x, y+1) ) /  8
   center  =  noise(x, y) / 4
   return corners + sides + center
end function

function InterpolatedNoise4(x as integer, y as integer) as double
   dim as double lx, ly, rx, ry, px, py, h, i1, i2
   dim as integer nx, ny
   lx = x
   ly = y
   nx = int(lx / fw * LEVEL4_DETAIL)
   ny = int(ly / fh * LEVEL4_DETAIL)
   rx = fw / LEVEL4_DETAIL
   ry = fh / LEVEL4_DETAIL
   px = (lx - (nx * rx)) / rx
   py = (ly - (ny * ry)) / ry
   i1 = interpolate(SmoothedNoise(nx, ny), SmoothedNoise(nx + 1, ny), px)
   i2 = interpolate(SmoothedNoise(nx, ny + 1), SmoothedNoise(nx + 1, ny + 1), px)
   h = interpolate(i1, i2, py)
   return h
end function

function InterpolatedNoise3(x as integer, y as integer) as double
   dim as double lx, ly, rx, ry, px, py, h, i1, i2
   dim as integer nx, ny
   lx = x
   ly = y
   nx = int(lx / fw * LEVEL3_DETAIL)
   ny = int(ly / fh * LEVEL3_DETAIL)
   rx = fw / LEVEL3_DETAIL
   ry = fh / LEVEL3_DETAIL
   px = (lx - (nx * rx)) / rx
   py = (ly - (ny * ry)) / ry
   i1 = interpolate(SmoothedNoise(nx, ny), SmoothedNoise(nx + 1, ny), px)
   i2 = interpolate(SmoothedNoise(nx, ny + 1), SmoothedNoise(nx + 1, ny + 1), px)
   h = interpolate(i1, i2, py)
   return h
end function

function InterpolatedNoise2(x as integer, y as integer) as double
   dim as double lx, ly, rx, ry, px, py, h, i1, i2
   dim as integer nx, ny
   lx = x
   ly = y
   nx = int(lx / fw * LEVEL2_DETAIL)
   ny = int(ly / fh * LEVEL2_DETAIL)
   rx = fw / LEVEL2_DETAIL
   ry = fh / LEVEL2_DETAIL
   px = (lx - (nx * rx)) / rx
   py = (ly - (ny * ry)) / ry
   i1 = interpolate(SmoothedNoise(nx, ny), SmoothedNoise(nx + 1, ny), px)
   i2 = interpolate(SmoothedNoise(nx, ny + 1), SmoothedNoise(nx + 1, ny + 1), px)
   h = interpolate(i1, i2, py)
   return h
end function

function InterpolatedNoise1(x as integer, y as integer) as double
   dim as double lx, ly, rx, ry, px, py, h, i1, i2
   dim as integer nx, ny
   lx = x
   ly = y
   nx = int(lx / fw * LEVEL1_DETAIL)
   ny = int(ly / fh * LEVEL1_DETAIL)
   rx = fw / LEVEL1_DETAIL
   ry = fh / LEVEL1_DETAIL
   px = (lx - (nx * rx)) / rx
   py = (ly - (ny * ry)) / ry
   i1 = interpolate(SmoothedNoise(nx, ny), SmoothedNoise(nx + 1, ny), px)
   i2 = interpolate(SmoothedNoise(nx, ny + 1), SmoothedNoise(nx + 1, ny + 1), px)
   h = interpolate(i1, i2, py)
   return h
end function


Dim Shared As Integer x, y
Dim As Double t0, t1
Dim Shared As __VECTOR__ map
Dim Shared As Double RenderGrid(0 To 128,0 To 128)

map.x = 32768
map.y = 32768

Print "start"
t0 = Timer
for y = 0 to 128
   for x = 0 to 128
      RenderGrid(x, y)=getHeight(x+map.x, y+map.y)
   next
next
t1 = Timer

Print t0,t1,t1-t0

Sleep
Last edited by JohnB on Mar 09, 2008 12:18, edited 1 time in total.
v1ctor
Site Admin
Posts: 3804
Joined: May 27, 2005 8:08
Location: SP / Bra[s]il
Contact:

Postby v1ctor » Mar 09, 2008 12:01

Without running the code, that's probably caused by the calls to Randomize. The algorithm used in RND was updated in 0.17 to be more precise and consistent in all platforms, but it is slower to initialize than the old one (that was just a wrapper for the C runtime).
Last edited by v1ctor on Mar 09, 2008 12:05, edited 1 time in total.
JohnB
Posts: 236
Joined: Jul 22, 2005 3:53
Location: Minnesota Arizona

Postby JohnB » Mar 09, 2008 12:03

I found what was causing the speed problem but would like someone to explain the differences in algorithm execution times.

In the noise function there is a randomize command. Execution time in the test program varied GREATLY depending on the algorithm used.

randomize 1+x*y+sin(x)*128+cos(y)*128_____t1-t0 = 18.182
randomize 1+x*y+sin(x)*128+cos(y)*128,0____t1-t0 = 18.182
randomize 1+x*y+sin(x)*128+cos(y)*128,1____t1-t0 = 0.734
no randomize_____________________________t1-t0 = 0.208

JohnB


Code: Select all

function noise(x as integer, y as integer) as double
   if x>-1 and y>-1 then
'      randomize 1+x*y+sin(x)*128+cos(y)*128
      randomize 1+x*y+sin(x)*128+cos(y)*128,1
      return rnd * 2 - 1
   else
      return 0
   end if
end function
JohnB
Posts: 236
Joined: Jul 22, 2005 3:53
Location: Minnesota Arizona

Postby JohnB » Mar 09, 2008 12:17

v1ctor,

Thanks for the reply. I did find the problem about 4:30 this morning and you are correct in your assumption. Randomize was the problem. Changed the algorithm to the C runtime library and execution speed increase by a factor of about 25. I now fly smoothly and enjoyably through Z!re's PIH world, but I want to rotate so I can fly where I want to.

Thanks again.

JohnB
Bunuel66
Posts: 76
Joined: May 19, 2006 19:56

Question

Postby Bunuel66 » Mar 09, 2008 12:23

I don't know the aim of the algorithm. Then, it is a bit unclear to me why it is needed to initialize the random generator at each call? Why not initializing it only at the start of the program?

Regards
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Postby MichaelW » Mar 09, 2008 12:33

On my system the ratio was about 5:1. Here are my results from a rough profile of the code (tot in seconds, others in % of total):

Code: Select all

v0.18.2:
gh   0.3
in   1.0
no  81.9
sn  16.3
in1  0.2
in2  0.2
in3  0.2
in4  0.2
tot 45.1

w/o randomize in noise
gh   1.9
in   6.7
no  70.5
sn  16.4
in1  1.1
in2  1.1
in3  1.1
in4  1.1
tot  6.4

v0.16:
gh   1.4
in   4.8
no  75.6
sn  15.0
in1  0.8
in2  0.8
in3  0.8
in4  0.8
tot  8.7

w/o randomize in noise
gh   1.9
in   6.5
no  70.5
sn  16.8
in1  1.1
in2  1.1
in3  1.1
in4  1.1
tot  6.5
cha0s
Site Admin
Posts: 5317
Joined: May 27, 2005 6:42
Location: Illinois
Contact:

Postby cha0s » Mar 09, 2008 22:34

Randomize is meant to be called few times, preferably once only. If you plan on getting random numbers, then changing the seed won't matter at all. You'll get random numbers either way.
JohnB
Posts: 236
Joined: Jul 22, 2005 3:53
Location: Minnesota Arizona

Postby JohnB » Mar 10, 2008 2:54

I am going modify the code Z!re posted for the Procedural Infinite Heightmap Generator so that Randomize is only called once. I want to see what effect it has on terrain generation. By changing the randomize algorithm to the C runtime library the procedural infinite heightmap generator, SDL/FPPNG version, runs at a frame rate of about 40 on a AMD Sempron 2600/ ATI 9600. This compares to Z!re original 0.16b code which at about 37 fps. When I removed randomize from the test program it only ran slightly faster.

Thanks to everyone.

JohnB
Last edited by JohnB on Mar 10, 2008 3:42, edited 2 times in total.
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Postby KristopherWindsor » Mar 10, 2008 3:07

Code: Select all

Randomize 1+x*y+Sin(x)*128+Cos(y)*128,1


This will give you the same number every time if the values of x and y do not change.
Do you want this, or complete randomness (at least as far as unpredictability goes)?

For example, this is "predictably random," and may or may not be what you want:

Code: Select all

' Is That Random?
' By Kristopher Windsor

Screenres 800, 600, 32

For i As Integer = 1 To 2
  For x As Integer = 0 To 799
    For y As Integer = 0 To 599
      Randomize 1 + x * y + Sin(x) * 128 + Cos(y) * 128, 1
      Pset (x, y), Rgb(Rnd * 256, Rnd * 256, Rnd * 256)
    Next y
  Next x
  Print "Done with round ", i
  Sleep
Next i


;-)
JohnB
Posts: 236
Joined: Jul 22, 2005 3:53
Location: Minnesota Arizona

Postby JohnB » Mar 10, 2008 6:40

This will give you the same number every time if the values of x and y do not change.


Yes. The code comes from Z!re's post for a Procedural Infinite Heightmap (PIH) Generator. If I travel through the world and come back to the same x,y point it should generate the same height map. Parameters for changing the PIH world are in the WoM.bi file.

http://www.freebasic.net/forum/viewtopic.php?t=10837&highlight=

I understand how randomize effect executions speed, but it also has another effect on the height maps generated. Randomize algorithms default,0,1,2,3 create similar world in PIH, smooth landscapes. Randomize algorithm 4, which is 24-bit low randomness creates very jagged worlds, small base very tall pyramids in PIH.

Nice example program.

Thanks

JohnB
Z!re

Postby Z!re » Mar 13, 2008 1:01

[Content removed at author's request]

Return to “General”

Who is online

Users browsing this forum: No registered users and 10 guests