Less puzzled

Some weeks ago, I made a posting in which I presented some code and then considered how it might be optimized and asked for input from readers. I was confident that I would not have found every possibility. Indeed, there were some useful comments, which I really appreciated. [It is nice to know that there is someone out there!]

Apart from the comments, I had an email from Michael Luber in Germany, who looked at the problem in some detail. With his permission, I have reproduced his results here …

I also like puzzles very much and, therefore, I would like to comment on this post.

I played around a bit and also found that much of what I could think of would probably addressed by most compilers.

However, in the end, I came up with this:

/*******************************************************************/
#define ITERATIONS 50
int mandelbrot(float a)
{
int i;
float b = a;
for (i=0; i<ITERATIONS; i++)
{
if (*((unsigned int*) &b) & (unsigned int)0x40000000)
{
return i;
}
b = b * b + a;
}
return i;
}
/*******************************************************************/

 

Here is what I considered:

  • Some compilers might initialize all uninitialized auto variables with zero, so I preferred to put a declaration of b with the assignment of a to it as a single statement. (As Peter already did).
  • I would rather let the variable i run from zero to (ITERATIONS – 1). This may save initializing it (see above), and saves the subtraction of 1 in the return statement.
  • This also allows i to be returned instead of ITERATIONS, if the for-loop runs to completion, which may save loading the constant ITERATIONS into a register (assuming i already is in a register).
  • For checking if the absolute value of a float is greater than 2, I just check for the second bit is set, which should work considering how floats are represented in memory. Of course, this “hack” introduces a hardware dependency, which is generally not a good idea. However, if the requirement is for performance above all, I could consider that. On x86-gcc, this trick reduces the check to a total of four instructions, including those for loading the float from stack as well as the conditional jump:
mov -0x8(%ebp),%eax
and $0x40000000,%eax
test %eax,%eax
je 0x4010bd

 

Maybe I would put this in a macro and add some compile-time checks to be safe, in case the compiler changes, or I go to 64-bit or something like that.

I’m also aware that my code checks for >=2 instead of >2, but when it comes to comparison of floating point numbers, this seems acceptable.

Want to stay up to date on news from Siemens Digital Industries Software? Click here to choose content that's right for you

Leave a Reply

This article first appeared on the Siemens Digital Industries Software blog at https://blogs.sw.siemens.com/embedded-software/2012/12/03/less-puzzled/