The Linux kernel uses several special capabilities of the GNU Compiler Collection (GCC) suite. These capabilities range from giving you shortcuts and simplifications to providing the compiler with hints for optimization. Discover some of these special GCC features and learn how to use them in the Linux kernel.
The article introduces some obscure yet useful GCC extensions with sample code from the linux kernel. The extensions are categorized into functionality and optimization. Some of my favorite extensions from the list are:
- Type Discovery. This is a simplified version of templates found in C++. But its pretty cool to write a generic min() or max() function using this extension.
- Range Extension. Now this is an awesome extension that can save some typing (or copy/pasting). It lets you use a range in Switch … Case statements. You can also initialize an array range with a value.
- Branch Prediction and Pre-fetching. These extensions are optimization hints that help the compiler to produce efficient machine code. Branch Prediction is used in if-else conditions to notify which condition is more likely to be true. Pre-fetching is manually populating the L1 and L2 cache with appropriate data which results in reduced latency, thus improving the performance.
———-
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
————-
anyone know what why this line is there:
void) (&_min1 == &_min2);
?
It has to do with typechecking.
Making a simple program:
int x = 10;
long y = 20;
long r = min(x, y);
Gives the following warning:
warning: comparison of distinct pointer types lacks a cast
Could you please explain further. For me the line (void) (&_min1 == &_min2); is still somewhat inexplicable, since it does not seem to do anything other than compare the two pointers of the temporary variables (which are always distinct) and cast the result to void. So it seems to me as an addendum to the macro (they must have first written it without this line) to keep GCC from generating warnings. Why GCC refrains from the warning after this line is not completely clear to me.
Maybe it’s in there in order to generate a warning.
Ah. That would make more sense. Thank you.
.
And having special optimizations in the compiler is nice. But, isn’t it a goal to have the OS as portable as possible to make it easier to port? Granted, GCC is readily available for most any platform, and readily enough ported to any other platform as needed, but so much for the claim of Linux using open standards, while at the same time purposely using compiler hacks that no other compiler has, making the code less portable.
Has Linux EVER been compiled with a non-GNU compiler?
To answer my own question…
In 2004 a German group apparently got the Linux 2.6 Kernel to compile using the Intel Compiler. It required patches and a custom pre-processor to convert some of the GCC directives. Interesting…
http://www.pyrillion.org/index.html?showframe=linuxkernelpatch.html
They claimed performance improvements of up to 40% for some limited areas of the kernel, and 8-9% overall performance improvement in general.
It is good to have such useful extensions, because it makes the code faster, and decreases chances of errors in the code. Pure C standard isn’t enough for the kernel
(and a small part of it is still platform-dependent ASM, anyway).
Portability of the Linux kernel is not in danger because gcc supports enough platforms.