Maximal Min() and Max()
Recent Linux kernel developments reveal that complex min() and max() macros increase compilation times, prompting proposals for new macros to simplify code while balancing type safety and efficiency.
Read original articleRecent developments in the Linux kernel have highlighted issues with the preprocessor macros min() and max(), which are extensively used in the kernel's C code. These macros, originally designed for simplicity, have evolved into complex constructs that can lead to significant increases in compilation time. A specific case was identified where a single line of code expanded to an excessive 47MB of preprocessor output due to nested calls to min() and min3(). This complexity has raised concerns among developers about the efficiency of kernel builds. In response, kernel developers have proposed changes to mitigate the problem, including the introduction of new macros that simplify the code while sacrificing some type safety. Linus Torvalds expressed concerns about the overly clever nature of the existing macros and suggested reverting to simpler forms, although many parts of the kernel now depend on the newer functionality. The ongoing discussion reflects the balance between maintaining type safety and ensuring efficient compilation times in kernel development.
- The complexity of min() and max() macros has led to increased kernel compilation times.
- A specific line of code expanded to 47MB of preprocessor output due to nested macro calls.
- New macros have been introduced to simplify code and improve compilation efficiency.
- Developers are concerned about the trade-off between type safety and compilation speed.
- Ongoing discussions among kernel developers aim to address these issues while maintaining functionality.
Related
Background of Linux's "file-max" and "nr_open" limits on file descriptors (2021)
The Unix background of Linux's 'file-max' and 'nr_open' kernel limits on file descriptors dates back to early Unix implementations like V7. These limits, set during kernel compilation, evolved to control resource allocation efficiently.
What are the ways compilers recognize complex patterns?
Compilers optimize by recognizing patterns like popcount, simplifying code for efficiency. LLVM and GCC use hardcoded patterns to match common idioms, balancing compile-time speed with runtime gains in critical code sections.
Tail Recursion for Macros in C
The blog discusses tail recursion for macros in C, introducing __VA_TAIL__() to enable real recursion, overcoming inefficiencies of traditional recursive macro calls. It showcases how tail recursion improves processing efficiency in macros.
Maximal Min() and Max()
Recent changes to the min() and max() macros in the Linux kernel have increased compilation times, prompting discussions on reverting to simpler macros to improve efficiency and reduce code expansion.
Clang vs. Clang
The blog post critiques compiler optimizations in Clang, arguing they often introduce bugs and security vulnerabilities, diminish performance gains, and create timing channels, urging a reevaluation of current practices.
- Many commenters emphasize the complexity of the current macros, which can lead to increased compilation times and bloated code.
- There is a debate on whether to continue using macros or to switch to function calls, with some arguing that inlining could mitigate performance issues.
- Some suggest that the language's limitations should be accepted, advocating for type-specific implementations instead of generic macros.
- Concerns about type safety and correctness are prevalent, with calls for thorough testing of the macros due to their complexity.
- Several commenters express frustration with the use of macros in C, suggesting that they complicate code unnecessarily.
The macros now do type-safe comparisons that work correctly with combinations of different argument types where this is possible, work in a constant context (eg defining array bounds), work correctly in the face of implicit type coercion and include a 3-way min and max that have these same desirable properties (same as the two way min and max).
The problem(s) are it’s a bit slow to compile and the preprocessor expansion (although not necessarily the final generated assembly - didn’t see anyone saying that) is a bit bloated.
So when you make a “why don’t they just…. ?”-suggestion, make sure your suggestion is at least as good as what they have now in terms of the desirable functionality and correctness and then tackles the actual problems in some way. I’m not sure all of the suggestions I have seen here and in the lwn comments succeed at meeting those two criteria.
(void) (&_x == &_y);
Is this... a check for type-compatibility? I don't think actually produces a compilation error if the types are incompatible.These macros are now so complex that they're reluctant to touch them. Seems like there is a clear need for some thorough tests here? This is exactly the sort of thing that is eminently testable.
Given the number of preprocessor hacks used in the kernel, and the amount of GCC-specific behavior that the codebase depends on, it seems like they are already halfway there.
Related
Background of Linux's "file-max" and "nr_open" limits on file descriptors (2021)
The Unix background of Linux's 'file-max' and 'nr_open' kernel limits on file descriptors dates back to early Unix implementations like V7. These limits, set during kernel compilation, evolved to control resource allocation efficiently.
What are the ways compilers recognize complex patterns?
Compilers optimize by recognizing patterns like popcount, simplifying code for efficiency. LLVM and GCC use hardcoded patterns to match common idioms, balancing compile-time speed with runtime gains in critical code sections.
Tail Recursion for Macros in C
The blog discusses tail recursion for macros in C, introducing __VA_TAIL__() to enable real recursion, overcoming inefficiencies of traditional recursive macro calls. It showcases how tail recursion improves processing efficiency in macros.
Maximal Min() and Max()
Recent changes to the min() and max() macros in the Linux kernel have increased compilation times, prompting discussions on reverting to simpler macros to improve efficiency and reduce code expansion.
Clang vs. Clang
The blog post critiques compiler optimizations in Clang, arguing they often introduce bugs and security vulnerabilities, diminish performance gains, and create timing channels, urging a reevaluation of current practices.