Live data from Hacker News

Why Const Doesn't Make C Code Faster

theartofmachinery.com

171–180 of 197 posts

Re: Why Const Doesn't Make C Code Faster

#171
post #108

The key difference between `const` and the `register` and `inline` keywords is that, despite all of them often flagging optimisations that the compiler can often work out anyway, `const` still aids human comprehension by declaring constraints, whereas the latter two do not. It seems that interprocedure optimisations in modern compilers make a lot of const-by-reference optimisations apply even when the code is mutable…

While specifying inline alone is useless for optimization, the inline specifier is important for another type of optimization: putting a function in a header file. If you put a function in a header file and don't mark it inline, that tends to be undefined behavior because it tends to violate the One Definition Rule, (both C and C++).

Force inlining code is actually quite a useful optimisation still. We have found many instances that after a few inline functions the compiler gives up and just calls the function instead. Force inlining certain low level functions has actually improved performance by several percent in our codebase.

Re: Why Const Doesn't Make C Code Faster

#172

I once had a very stubborn intern who decided to add as much const as he could in our codebase. What followed was a heated discussion and I did a global replace of const by nothing. The main problem with const is that it's ugly, it's viral and it does not add any value to the code. And I know all the supposedly good things about this, but I never found any real usage in practice.

You should fire yourself. Seriously. Understanding which object parameters to a function are inputs and which ones are modified is key information about the behavior of a function. It's omission requires devs to divine the intent from the name and hope that every previous dev was a good citizen w.r.t keeping function names accurate to intent. Finding and replace const with empty is the moral equivalent of replacing a…

With "const" you still need to rely on devs being good citizens since const can be trivially casted away.

I've been programming in C for 25+ years. const is clutter.

Re: Why Const Doesn't Make C Code Faster

#173

Earlier quoted context omitted.

So it seems that you are sort of talking about a function that is memoizable but not pure. Pure has no mutation of any global state. So hypothetically touching the heap means not pure - if somehow others can see it.

So where do we draw the line? Of course, no real computer implementation of any language is going to be able to generate fundamentally pure code because in the end they're going to be mutating memory (at the very least the program counter). That's not a very useful distinction, and usually one talks about "purity" at a conceptual level. The language provides a layer of abstraction in which things can be considered pu…

I think that is a good point at the end. Pure may be defined in regards to the language. So allocating memory in C may make a function unpure but something other languages may still be pure.

Re: Why Const Doesn't Make C Code Faster

#174

Earlier quoted context omitted.

Static but not inline functions will trigger warnings of unused functions. Static and inline does not trigger this.

> Static but not inline functions will trigger warnings of unused functions. Well, isn't it true? It's true also in the inline case. I consider it strange behavior not to emit an explicitly enabled warning for a case that definitely satisfies the warning conditions. > Static and inline does not trigger this. Tried -Wunused-function in gcc 6.3.0 and clang 3.8.1-24, with an unused-but-defined function declared "static…

It turns out that the clang warnings work differently in header files, specifically. In my test I just put the static inline function in a C file. clang does however not trigger -Wunused-function when the static inline function is included from a header. The code is the same after pre-processor expansion.

IMO these special cases just add to the confusion and my criticism of strange behavior, but I stand corrected on the actual behavior of the two compilers.

Re: Why Const Doesn't Make C Code Faster

#175

I hardly ever bother optimizing my code anymore, with -O3 nothing I do ever really seems to make a difference. The real reason to use "const" is to show intent. See "Const and Rigid Parameters" in this wonderful article about the Doom 3 source code: https://kotaku.com/the-exceptional-beauty-of-doom-3s-source-...

I find that I can sometimes get significant speedups by changing data access patterns when considering cache. I have found this to be the first and most valuable thing to tune, before attempting SIMD.

Re: Why Const Doesn't Make C Code Faster

#176
post #171
post #108

Earlier quoted context omitted.

While specifying inline alone is useless for optimization, the inline specifier is important for another type of optimization: putting a function in a header file. If you put a function in a header file and don't mark it inline, that tends to be undefined behavior because it tends to violate the One Definition Rule, (both C and C++).

Force inlining code is actually quite a useful optimisation still. We have found many instances that after a few inline functions the compiler gives up and just calls the function instead. Force inlining certain low level functions has actually improved performance by several percent in our codebase.

From the language standpoint, the inline specifier doesn't force the compiler to inline the function. But I guess some compilers could provide guarantees that go beyond what the spec says.

Re: Why Const Doesn't Make C Code Faster

#177

Earlier quoted context omitted.

Yes, I know what std::launder does, and that document contains some of my own thoughts: namely, placement new (the only use I've seen suggested) should automatically launder, and std::launder should just not exist.

AFAIK placement new does launder. But both new and launder have no effect on their argument (well, placement new of course constructs an object there), they only 'bless' pointer returned from it. The use case is if you placement new on some byte storage. Now you want to access the object stored there, and of course you do not want to placement new the storage again, nor you have cached the result of the previous plac…

> AFAIK placement new does launder. But both new and launder have no effect on their argument (well, placement new of course constructs an object there), they only 'bless' pointer returned from it.

I may be misunderstanding, but this seems to directly contradict what the linked paper says:

> Note that std::launder() does not “white wash” the pointer for any further usage.

> The obvious question is, why don’t we simply fix the current memory model so that using data where placement new was called for implicitly always does launder?

Re: Why Const Doesn't Make C Code Faster

#178
post #63
post #58

Earlier quoted context omitted.

Having a constant size probably made it easy for the compiler to properly generate bytecode that uses vectorized instructions

I would say that's unlikely. SIMD instructions don't usually get used by normal compilers without very specific loops that make sure there are no obstacles to vectorization. Also the best way to use SIMD is to loop through a large array of two and do very simple operations with them. Modern CPUs actually have three (I think) floating point slots so their total floating point throughput isn't simply a fraction of the…

> SIMD instructions don't usually get used by normal compilers without very specific loops

Compilers are smart. Even Java's JIT will generate SIMD instructions pretty well

Re: Why Const Doesn't Make C Code Faster

#179
post #89

Earlier quoted context omitted.

BINGO!!! The pointer is constant, not the item being pointed to. Since you’re dereferencing the pointer, i.e. accessing the non-const bits, the compiler must reload.

The examples in the articles are non-constant pointers to constant data. If you want to declare the pointer itself const, you need to do it after the asterisk. const int* const instead of const int*

Dammit! Why can I never keep the syntax straight?!

Re: Why Const Doesn't Make C Code Faster

#180

Earlier quoted context omitted.

Not if it is defined in another translation unit and you are not using LTO.

In other words, the compiler can infer this from the function definition (or at least clang does), but it cannot infer this from a function declaration, because the implementation is missing - unless you are using LTO like the parent mentions.

sometimes it cannot infer it even from function, for example, here is a function that in my particular OS gets me a pointer to my library's globals. To my code the returned pointer never changes, but the compiler has NO way to tell this function is const without my annotation

  void* __attribute__((const)) getGlobals(void) {
    void* ret;

    asm (
      " ldr %0, [r9]      \n"
      " ldr %0, [%0, %1]  \n"
      : "=r"(ret)
      : "I"(MY_MODULE_ID)
      :
    );
    return ret;
  }
Post reply on HN