faster using macros

Started by
24 comments, last by Mr Grinch 16 years, 1 month ago
The compiler knows which is faster. By using inline you give the compiler more information in making that decision.
Advertisement
A bad test case. Even if both were macros the code inside is different, so it's hard to tell. It could depend on what compiler you're using, and even what hardware you're using.

I don't think this subject will ever be as black and white as that. However, I would use inline functions simply because they're typesafe and less prone to errors such as those previously mentioned.
When quake was written, compilers might not have been as good. The macro is applied before the compiler ever sees the file so it can compensate for a compiler that doesn't support inlining.
Quote:
A bad test case. Even if both were macros the code inside is different


would they not produce the same bitcode though, I thought (condition)?true:false
was just an alernative way to write an if else statement, when you are returning one value anyway.
Quote:Original post by Vorpy
When quake was written, compilers might not have been as good. The macro is applied before the compiler ever sees the file so it can compensate for a compiler that doesn't support inlining.


More to the point, Quake was written in a programming language without the inline keyword. C89 does not support inline functions.
These micro-optimizations won't get you anywhere. Getting rid of the conditionals should be your major concern.

This function yiels -1/+1 for negative/zero or positive:
int sign(int i){    return ((i >> 30) & ~1) + 1;}


And this function yields -1/0/+1 for negative/zero/positive:
int sign(int i){    unsigned u = -i;    return (i >> 31) | (u >> 31);}
where did u learn all these tricks?
You just think about how numbers are represented in two's complement. The sign is the bit at position 31, so if you shift a signed number 31 to the right, you get either 00000000000000000000000000000000 (0) for positive numbers or 11111111111111111111111111111111 (-1) for negative numbers.

But since you don't want 0 and -1 but instead 1 and -1, you just multiply by 2 and add 1 (2*0+1 = 1 and 2*-1+1 = -1). That would be (i >> 31) * 2 + 1 or ((i >> 31) << 1) + 1.

I personally don't like to shift right by 31 and then shift left by one, so I just shift right by 30 and mask the least significant bit out with &~1 which is essentially the same.

You basically learn this stuff when you program in assembly language where you can do even cooler stuff because you can access the status flags.

Here's another gem for computing the absolute value of a signed integer:

int abs(int i){    int m = i >> 31;    // m is either 0 (i positive) or -1 (i negative)    return (i ^ m) - m; // invert bits and subtract -1 (add 1) if i was negative}

To invert the sign of a number in two's complement, you invert all the bits and add 1. Since we only want to do this here if i is negative, we compute the sign and use that as a mask.
If i was negative, i & -1 -(-1) yields -i.
If i was positive, i & 0 - 0 yields i.
I understand how it works but I would never have thought of it.
Quote:Original post by staticVoid2
where did u learn all these tricks?


Plenty of references out there

This topic is closed to new replies.

Advertisement