Thread: macro functions/efficiency tricks (old-style?)

  1. #1
    Registered User
    Join Date
    Oct 2011
    Posts
    8

    macro functions/efficiency tricks (old-style?)

    Hi,

    taken from the PD code section from Numerical Recipes Book for C from 1992, a macro is defined as follows:

    Code:
    #define SQR(a) ((sqrarg=(a)) = 0.0 ? 0.0 : sqrarg * sqrarg )
    This may be old-style, but are there any benefits today in testing for 0 to avoiding multiplies with 0.0 (for efficiency I suppose?).
    And why are the a-parameter assigned to sqrarg and not used directly in the expression?

    Thanks!

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    It seems it would only be beneficial if a great majority of the values being squared are equal to 0.0 -- if that's the case, surely you know it is, and the optimization should be performed at a higher level in order to make it visible and explicit, not tuck it away hidden inside some SQR() macro.

    I judge it to be pointless.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    Registered User
    Join Date
    Oct 2011
    Posts
    8
    I also refer back to the days when you could suggest to the compiler to make key variables to be stored in the registers (with register keyword),
    though this is only a suggestion and could not be demanded. Today, it seem to be possible to use this, but would make no point to use them (in at least most cases(?)).
    Maybe some other platforms would make use of this?
    Often I am little confused about the role of the C programmer today and how detail-specific a C programmer should be when dealing with performance issues. I mean, when to do the best choices. I know that in most cases a modern compiler would in most cases out-compete a programmer when it comes to small efficiency snippets and the focus should be in making the most efficient algorithms in the whole.

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Generally, the compilers these days will produce the best possible code that does what you have written. That doesn't mean what you've written is necessarily the most optimal way to do something.

    The role of the programmer in optimization will never really go away, because compilers can't design programs or think about things. They can, however, figure out how to squeeze the best performance out of a specific set of statements. Two different things.

    Most really serious optimizations are related to algorithm choice and efficient use of CPU cache. A compiler can't help you there.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  5. #5
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    GCC, for example, completely ignores the register keyword.

  6. #6
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    Also, the snippet you posted will be slower in most cases because of the branch. Branching is bad in modern processors with deep pipelines.

    It's not so bad if the path taken is predictable, since modern predictors are very good.

    However, if your input has 50% chance of being 0.0 and 50% chance of being not 0.0, it will probably be much slower than just multiplying by itself.

    It depends on performance of the FPU, too. If the compare and branch instruction takes equal or longer than multiplication, it will obviously be slower.

  7. #7
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    One thing nobody mentioned yet is that sqrarg still have to be declared somewhere for it to compile. Being done this way is likely to encourage the kind of thing that would make it not threadsafe. e.g. sqrarg being a global.
    Its probably slower than a plain old multiply, possibly even after taking the frequency of zeros being taken into account.
    It also has a major bug unless you're written it out incorrectly. It's assigning zero instead of comparing to zero.
    The macro does perform common subexpression elimination, but the right way to do that is either for the programmer to use a temp variable on their own or for it to be a function call.

    In summary, do not use this macro in modern code. Even 20 years ago it would have been of very dubious benefit.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  8. #8
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    Agree with everyone else that this is probably a bad idea unless used to solve a really specific problem.

    Actually, the right way to do common subexpression elimination is to enable optimization in the compiler.

    Aside from the problems with breaking branch prediction in any reasonably modern processor, this also fails because it creates lots of extra work if the argument to square is anything but a double. For CPUs without hardware floating point support, you've just added hundreds of lines of code to handle something which should have been done with one integer multiply instruction.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,662
    > GCC, for example, completely ignores the register keyword.
    Except for the part about "you can't point at a register".

    > It depends on performance of the FPU, too. If the compare and branch instruction takes equal or longer than multiplication...
    Worse still, clever instruction scheduling could deliver the FP mult result "for free", if the compiler can make the CPU do something else useful between issuing the mult instruction and needing the result.

    Then there's the whole "comparing floats for equality" issue as well.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. macro functions console appi
    By In_Control001 in forum C Programming
    Replies: 2
    Last Post: 02-17-2010, 03:22 PM
  2. An array of macro functions?
    By someprogr in forum C Programming
    Replies: 6
    Last Post: 01-28-2009, 07:05 PM
  3. pls post here tricks that you know of in C/C++, thanks
    By mickey in forum C++ Programming
    Replies: 55
    Last Post: 06-12-2003, 04:28 PM
  4. comment on my coding style and if i use functions well
    By Unregistered in forum C++ Programming
    Replies: 14
    Last Post: 03-09-2002, 07:24 AM
  5. Tips And Tricks
    By The15th in forum Windows Programming
    Replies: 7
    Last Post: 01-03-2002, 07:12 AM