Author: Ricardo Gibert
Date: 03:06:08 07/07/03
Go up one level in this thread
On July 07, 2003 at 04:26:00, Gerd Isenberg wrote:
>On July 07, 2003 at 01:54:57, Uri Blass wrote:
>
>>On July 07, 2003 at 00:56:37, Reinhard Scharnagl wrote:
>>
>>>On July 06, 2003 at 23:25:00, Uri Blass wrote:
>>>
>>>>In movei I have a number between 0 and 255 and I want to do some functions for
>>>>every 1 that it has in its binary representation(number of functions to
>>>>implement is the same as the number of 1's in the number and there is a
>>>>different function based on the value of the 1)
>>>>
>>>>I do not like to call functions because functions use local varaibles and
>>>>generating a copy of the local varaibles only to forget them may take computer
>>>>time and I also do not use the functions more than once.
>>>>
>>>>I thought to use switch(see the code later in this post) but the problem is that
>>>>switch continue to do everything without break and I want to have switch that
>>>>does not continue to do everything but does not quit and simply forget about the
>>>>fact that I called switch.
>>>>
>>>>Here is the type of the code that I plan to have now.
>>>>I do not like all the if (number&2) or if (number&4) and the question is if I
>>>>can do it faster.
>>>
>>>How about:
>>>
>>>_work:
>>>switch (number) {
>>>case [all numbers matching 0x01]:
>>> /* do list of 0-commands */;
>>> if ((number &= ~0x01) != 0) goto _work;
>>> break;
>>>case [all numbers left matching 0x02]:
>>> /* do list of 1-commands */;
>>> if ((number &= ~0x02) != 0) goto _work;
>>> break;
>>>case [all numbers left matching 0x04]:
>>> /* do list of 2-commands */;
>>> if ((number &= ~0x04) != 0) goto _work;
>>> break;
>>>case [all numbers left matching 0x08]:
>>> /* do list of 3-commands */;
>>> if ((number &= ~0x08) != 0) goto _work;
>>> break;
>>>case 0x10: case 0x30: case 0x50: case 0x70:
>>>case 0x90: case 0xB0: case 0xD0: case 0xF0:
>>> /* do list of 4-commands */;
>>> if ((number &= ~0x10) != 0) goto _work;
>>> break;
>>>case 0x20: case 0x60: case 0xA0: case 0xE0:
>>> /* do list of 5-commands */;
>>> if ((number &= ~0x20) != 0) goto _work;
>>> break;
>>>case 0x40: case 0xc0:
>>> /* do list of 6-commands */;
>>> if ((number &= ~0x40) == 0) break;
>>>case 0x80:
>>> /* do list of 7-commands */;
>>> break;
>>>}
>>>
>>>Or alternative by doubling code:
>>>
>>>_work:
>>>switch (number) {
>>>case 0x01:
>>> /* do list of 0-commands */;
>>> break;
>>>case [all numbers left matching 0x01 except 0x01]:
>>> /* do list of 0-commands */;
>>> number &= ~0x01; goto _work;
>>>
>>>case 0x02:
>>> /* do list of 1-commands */;
>>> break;
>>>case [all numbers left matching 0x02 except 0x02]:
>>> /* do list of 1-commands */;
>>> number &= ~0x02; goto _work;
>>>
>>>case 0x04:
>>> /* do list of 2-commands */;
>>> break;
>>>case [all numbers left matching 0x04 except 0x04]:
>>> /* do list of 2-commands */;
>>> number &= ~0x04; goto _work;
>>>
>>>case 0x08:
>>> /* do list of 3-commands */;
>>> break;
>>>case [all numbers left matching 0x08 except 0x08]:
>>> /* do list of 3-commands */;
>>> number &= ~0x08; goto _work;
>>>
>>>case 0x10:
>>> /* do list of 4-commands */;
>>> break;
>>>case 0x30: case 0x50: case 0x70:
>>>case 0x90: case 0xB0: case 0xD0: case 0xF0:
>>> /* do list of 4-commands */;
>>> number &= ~0x10; goto _work;
>>>
>>>case 0x20:
>>> /* do list of 5-commands */;
>>> break;
>>>case 0x60: case 0xA0: case 0xE0:
>>> /* do list of 5-commands */;
>>> number &= ~0x20; goto _work;
>>>
>>>case 0x40:
>>> /* do list of 6-commands */;
>>> break;
>>>case 0xc0:
>>> /* do list of 6-commands */;
>>>
>>>case 0x80:
>>> /* do list of 7-commands */;
>>> break;
>>>}
>>>
>>>Regards, Reinhard
>>
>>I think that the idea of case is when I have single values and not to give a lot
>>of options in many cases.
>>
>>Maybe it is better not to use case but to use if and I do not know.
>>
>>Uri
>
>Hi Uri,
>
>if you ask for every single bit in a byte, you need eight ands (test) with
>conditional jumps. A switch with consecutive range is almost implemented as a
>jump-table and is like _one_ conditional jump. If your statements
>correspondating with the set bits are relatively short and branchless, i would
>prefere speed against size and the switch approach. But you have about 128 times
>the code size of the if-approach. It's a tradeoff and you may try both
>approaches.
>
>To get rid of the range checking code before using the indirect jmp (< 0 and >
>255) one may use a ms-specific keyword in msvc, but sorry, i have forgotten it,
>because i most often use arrays of function pointers for that purpose.
>
>// if approach
>if ( bits & 1 )
> do1(); // inlined functions
>if ( bits & 2 )
> do2();
>...
>if ( bits & 128 )
> do128();
>
>// switch/case approach
>switch (bits)
>{
>case 0:
> break;
>case 1:
> do1();
> break;
>case 2:
> do2();
> break;
>case 3:
> do1();
> do2();
> break;
>case 4:
> do4();
> break;
>...
>case 255:
> do1();
> do2();
> do4();
> do8();
> do16();
> do32();
> do64();
> do128();
> break;
>}
>
>Regards,
>Gerd
In between the 8 if statement approach and one 256-way switch statement would be
two 16-way switch statements. There is also the possibility of two 8-way plus
one 4-way switch statements too.
It is better to do the 8 if statement approach first, because it makes it
simpler and easier to debug everything. After everything is debugged and
working, use a profiler to determine whether optimizing would really payoff.
Most often the conclusion is that it would not and a lot of extra work will be
saved. Also, the benefits of simpler clearer code is not to be underestimated.
This page took 0 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.