Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: question about optimizing code

Author: Gerd Isenberg

Date: 01:26:00 07/07/03

Go up one level in this thread


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



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.