POV-Ray : Newsgroups : povray.general : Making faster #switch statements Server Time
12 Aug 2024 09:21:12 EDT (-0400)
  Making faster #switch statements (Message 1 to 10 of 15)  
Goto Latest 10 Messages Next 5 Messages >>>
From: Martin Magnusson
Subject: Making faster #switch statements
Date: 4 Mar 1999 18:53:22
Message: <36df1cf2.0@news.povray.org>
I'm working on a method of making cloth, and I posted a version of it in
.binaries.animations, but now I'm trying to make it faster. I used to have
this statement

#declare Unstretched = sqrt(pow(k*Normal_Length,2) +
pow(l*Normal_Length,2));

which is evaluated 24*16*16*4 times for each frame. Since Unstretched really
can have only five values, I thought I should precompute them and use a
#switch statement to choose, so I changed that line for the following:

#switch (abs(k) + abs(l))
  #case (1)  #declare Unstretched = Unstretched1;  #break
  #case (2)
    #if ((k=0) | (l=0))
      #declare Unstretched = Unstretched3;
    #else
      #declare Unstretched = Unstretched2;
    #end
  #break
  #case (3)  #declare Unstretched = Unstretched5;  #break
  #case (4)  #declare Unstretched = Unstretched4;  #break
#end

but it seems like that *increased* the parse time by about 50%. I thought
that just picking a precomputed value would be faster than calculating
Pythagoras' theorem. Did I do something wrong, or is #switch really that
slow?

--
Martin Magnusson
e-mail: Mar### [at] studentuuse
www-site: http://www.geocities.com/SoHo/9946/


Post a reply to this message

From: Anthony Bennett
Subject: Re: Making faster #switch statements
Date: 4 Mar 1999 22:35:25
Message: <36DF52AE.726E3BB1@panama.phoenix.net>
Hi. Glad you started posting some code.

Yes, as far as I know, in C, switch is extremely slow when compared to if. I
recommend you use that.

Here's how I would do it.

#declare Value=abs(k) + abs(l);
#if (Value=1) #declare Unstretched = Unstretched1;  #end
#if (Value=3) #declare Unstretched = Unstretched5;  #end
#if (Value=4) #declare Unstretched = Unstretched4;  #end

#if (Value=2)
    #if ((k=0) | (l=0))
     #declare Unstretched = Unstretched3;
    #else
     #declare Unstretched = Unstretched2;
    #end
#end


Post a reply to this message

From: Remco de Korte
Subject: Re: Making faster #switch statements
Date: 4 Mar 1999 22:46:41
Message: <36DF5350.C7DA7158@xs4all.nl>
Assuming you're using 3.01 why not use a (small) array?
That's probably the fastest you can get.

Regards,

Remco

Martin Magnusson wrote:
> 
> I'm working on a method of making cloth, and I posted a version of it in
> .binaries.animations, but now I'm trying to make it faster. I used to have
> this statement
> 
> #declare Unstretched = sqrt(pow(k*Normal_Length,2) +
> pow(l*Normal_Length,2));
> 
> which is evaluated 24*16*16*4 times for each frame. Since Unstretched really
> can have only five values, I thought I should precompute them and use a
> #switch statement to choose, so I changed that line for the following:
> 
> #switch (abs(k) + abs(l))
>   #case (1)  #declare Unstretched = Unstretched1;  #break
>   #case (2)
>     #if ((k=0) | (l=0))
>       #declare Unstretched = Unstretched3;
>     #else
>       #declare Unstretched = Unstretched2;
>     #end
>   #break
>   #case (3)  #declare Unstretched = Unstretched5;  #break
>   #case (4)  #declare Unstretched = Unstretched4;  #break
> #end
> 
> but it seems like that *increased* the parse time by about 50%. I thought
> that just picking a precomputed value would be faster than calculating
> Pythagoras' theorem. Did I do something wrong, or is #switch really that
> slow?
> 
> --
> Martin Magnusson
> e-mail: Mar### [at] studentuuse
> www-site: http://www.geocities.com/SoHo/9946/


Post a reply to this message

From: Phoenix
Subject: Re: Making faster #switch statements
Date: 5 Mar 1999 05:26:58
Message: <MPG.1149d0093256ed4f9896a0@news.povray.org>
'T was on Fri, 5 Mar 1999 00:25:10 +0100,
that Martin Magnusson wrote:
> but it seems like that *increased* the parse time by about 50%. I thought
> that just picking a precomputed value would be faster than calculating
> Pythagoras' theorem. Did I do something wrong, or is #switch really that
> slow?

The switch statement is already slow in compiled code (C, that is). It's 
total horror when used in an interpreted language like POV's. Use #if if 
you can.

Phoenix

-- 
eag### [at] telekabelnl                       http://users.telekabel.nl/eagle
------------------------------------------------------------------------
The POV-Ray VFAQ: http://iki.fi/warp/povVFAQ.html


Post a reply to this message

From: Margus Ramst
Subject: Re: Making faster #switch statements
Date: 5 Mar 1999 06:38:06
Message: <36DFC21D.23FAFB0B@peak.edu.ee>
Damn. I was convinced that #swich is faster and used it whenever I
could. It is faster in BASIC, if I'm not mistaken (or am I wrong there,
too?)

Margus

Phoenix wrote:
> 
> The switch statement is already slow in compiled code (C, that is). It's
> total horror when used in an interpreted language like POV's. Use #if if
> you can.
> 
> Phoenix
>


Post a reply to this message

From: Rudy Velthuis
Subject: Re: Making faster #switch statements
Date: 5 Mar 1999 07:15:44
Message: <36dfcaf0.0@news.povray.org>
Margus Ramst schrieb in Nachricht <36DFC21D.23FAFB0B@peak.edu.ee>...
>Damn. I was convinced that #swich is faster and used it whenever I
>could. It is faster in BASIC, if I'm not mistaken (or am I wrong there,
>too?)

I'm not sure switch () is generally slower in C (don't know about POV-Ray or
BASIC) at all. Good optimizers will code a range of consecutive values (e.g.
4, 5, 6, 7, and 8) as a calculated jump or a jump table. But if the values
are not arranged so well, you will have code similar to the if ()
statements. In fact a switch statments should at least be converted to
something like:

if (value == value1) dothis;
else if (value == value2) dothat;
else if (value == value3) .... etc.etc.
..
else dothedefault;

The speed increase should come from the fact, that "value" doesn't have to
be reloaded, but can be compared against an array of values and according
jumps to code. Now C could be a bit difficult from my favourite language,
Pascal, in that code can fall through (if there's not break) to the next
case statement, but I'm not sure this will really slow things down. The
break statement should just be translated into a jump to the end of the
switch.

Now the implementation of #switch in POV-Ray could be different, because
POV-Ray is really interpreted, so pre-calucalted jumps or jump tables etc,
are out of the question here.

--
Rudy Velthuis


Post a reply to this message

From: Rudy Velthuis
Subject: Re: Making faster #switch statements
Date: 5 Mar 1999 07:15:46
Message: <36dfcaf2.0@news.povray.org>
Phoenix schrieb in Nachricht ...

>The switch statement is already slow in compiled code (C, that is). It's
>total horror when used in an interpreted language like POV's. Use #if if
>you can.


What makes you assume switch is slow in compiled code (C, Pascal, compiled
Basic) at all?

See my reply to Margus' reply too.

--
Rudy Velthuis


Post a reply to this message

From: Phoenix
Subject: Re: Making faster #switch statements
Date: 5 Mar 1999 07:24:04
Message: <MPG.1149eb79f78933399896a1@news.povray.org>
'T was on Fri, 5 Mar 1999 12:59:14 +0100,
that Rudy Velthuis wrote:
> What makes you assume switch is slow in compiled code (C, Pascal, compiled
> Basic) at all?

This may have to do with the compiler I once wrote for a simple version 
of C. I had a hell of a time getting a working executable with a switch 
statement, let stand the horror of optimizing the code in such a fashion 
that would please my teacher...

In general, the time it takes to read in a jump table is far greater than 
just using the jump system that gets generated by an if-clause.

Phoenix

-- 
eag### [at] telekabelnl                       http://users.telekabel.nl/eagle
------------------------------------------------------------------------
The POV-Ray VFAQ: http://iki.fi/warp/povVFAQ.html


Post a reply to this message

From: Thorsten Froehlich
Subject: Re: Making faster #switch statements
Date: 5 Mar 1999 10:17:19
Message: <36dff57f.0@news.povray.org>
In article <MPG.1149eb79f78933399896a1@news.povray.org> , eag### [at] telekabelnl
(Phoenix) wrote:

> In general, the time it takes to read in a jump table is far greater than
> just using the jump system that gets generated by an if-clause.

That depends a lot on the density of the case conditions you have. Assume
you write a switch statement for the tokenizer in POV-Ray: You have most of
the ASCII characters and a high density of the numbers you compare. So the
compiler generates a jump table. It will most likely be somewhere around 128
entries. You need two comparisons plus branches (range checking) and one
jump. However, using a "if-clause jump system" you will in the worst case
have 128 comparsions and 128 conditional branches. Even if the processor
pipeline never gets interrupted you will still have 256 instructions
compared to only about 8 instructions. Compared to the "if-clause jump
system" average which would (assuming equal distribution, also for ASCII
characters (I used as example) it might be even worse) be 128 instructions -
not to mention the memory overhead...


     Thorsten


Post a reply to this message

From: Ron Parker
Subject: Re: Making faster #switch statements
Date: 5 Mar 1999 11:03:16
Message: <36e00044.0@news.povray.org>
On Fri, 05 Mar 1999 09:17:18 -0600, Thorsten Froehlich 
	<fro### [at] charliecnsiitedu> wrote:
>In article <MPG.1149eb79f78933399896a1@news.povray.org> , eag### [at] telekabelnl
>(Phoenix) wrote:
>
>> In general, the time it takes to read in a jump table is far greater than
>> just using the jump system that gets generated by an if-clause.
>
>That depends a lot on the density of the case conditions you have. Assume
>you write a switch statement for the tokenizer in POV-Ray: You have most of
>the ASCII characters and a high density of the numbers you compare. So the
>compiler generates a jump table. It will most likely be somewhere around 128
>entries. You need two comparisons plus branches (range checking) and one
>jump.

This depends on your compiler.  I've seen modern compilers do one of two 
things when given a switch statement like

switch (i) {
  case 1: foo(); break;
  case 2: bar(); /* fall through */
  case 4: baz(); break;
  default: quux(); break;
}

One compiler would make this look like: 

  mov  esi, ebp+i
  dec  esi
  test esi, FFFFFFFC
  jnz  default
  mov  ebx, table[esi*4]
  jmp  [ebx]
table:
  .dd  case1
  .dd  case2
  .dd  default
  .dd  case4
case1: 
  call foo
  jmp  end
case2: 
  call bar
case4: 
  call baz
  jmp  end
default: 
  call quux
end:
 ...

The other (older, less efficient compiler) would make it look like:

  mov  eax, ebp+i
  dec  eax
  jz   case1
  jl   default
  dec  eax
  jz   case2
  jl   default
  sub  eax, 2
  jz   case4
  jmp  default
case1: 
  (...same code as above...)


Both look no less efficient than what you'd expect from an if-else 
chain.  The jump table might take up space, but it's pretty quick
to execute.  Note the fancy footwork in the first case: it does the 
range checking for you in only three instructions, and only one 
subtraction.  You can always do this when the table is a power-of-two 
size.  If it makes sense to use a jump table in the first place, you 
can always pad it to the next power of two.  All of this is, of 
course, way off topic. :)


Post a reply to this message

Goto Latest 10 Messages Next 5 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.