August 03, 2014
This all seems to have a very simple solution, to use something like: expect()

GCC for example has an intrinsic, __builtin_expect() that is used to notify the compiler of a data constraint it can use in optimization for branches.  Why not make something like this a first-class citizen in D (and even expand the concept to more than just branch prediction)?

That way you don't have to hijack the meaning of assert(), but optimizations can be made based on the condition.  __buitin_expect() in gcc usually just figures the expected condition is fulfilled the vast majority of the time, but it could be expanded to make a lack of fulfillment trigger an exception (in non-release mode).  And the compiler is always free to optimize with the assumption the expectation is met.

On Sunday, 3 August 2014 at 19:47:27 UTC, David Bregman wrote:
> I am creating this thread because I believe the other ones [1,6] have gotten too bogged down in minutiae and the big picture has gotten lost.
>
> ...
>
> References:
> [1]: http://forum.dlang.org/thread/lrbpvj$mih$1@digitalmars.com
> [2]: http://dlang.org/overview.html
> [3]: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html
> [4]: http://blog.regehr.org/archives/213
> [5]: http://en.wikipedia.org/wiki/Heisenbug
> [6]: http://forum.dlang.org/thread/jrxrmcmeksxwlyuitzqp@forum.dlang.org
August 03, 2014
On Sunday, 3 August 2014 at 23:24:08 UTC, Martin Krejcirik wrote:
> On 3.8.2014 21:47, David Bregman wrote:
>> Walter has proposed a change to D's assert function as follows [1]:
>> "The compiler can make use of assert expressions to improve
>> optimization, even in -release mode."
>
> Couldn't this new assert behaviour be introduced as a new optimization
> switch ? Say -Oassert ? It would be off by default and would work both
> in debug and release mode.

That would be an improvement over the current proposal in my opinion, but I see some issues. One is the general argument against more compiler switches: complexity, and people will always enable stuff that seems like it might give the fastest code. Another is how do you mix and match code which is meant to be compiled with or without the switch? I suppose it could also be used in complement to a new function that has the proposed behavior regardless of switches.

Regardless, it goes to show there exists a design space of possible alternatives to the proposal.
August 03, 2014
On Sunday, 3 August 2014 at 22:57:24 UTC, Ola Fosheim Grøstad wrote:

> Turning asserts in program+libaries into globally available axioms is insane.

I guess this is the heart of the difference in the way DbC programmers program.

I know that program proving is impossibly hard, so my asserts are a kind of short cut on it.

I use asserts to define my architecture.

So that I can say, "

In my architecture, I know, by design, certain eventualities will never occur.

I don't expect any compiler to be able prove that for me (although it would be nice if it could), but I certainly will be relying on these facets of the architecture."

When I assert, I'm stating "In my architecture, as I designed it, this will always be true, and everything in the code downstream of here can AND DOES rely on this.

My code explicitly relies on these simplifying assumptions, and will go hideously wrong if those assumptions are false.... So why can't the compiler rely on them too?

Of course it can, as every single line I write after the assert is absolutely relying on the assert being true."

My asserts are never "I believe this is true".

They are _always_ "In this design, the following must be true, as I'm about to code absolutely relying on this fact."

And if the compiler chooses to rely on it too... I can absolutely gaurantee you that differing optimizations will be the least of my worries if the expression is false.

However, that said, it is very clear to me that this is a very different usage of "assert" to what many of colleagues do.

Hence my suggestion we make explicit by differing names what usage we mean.

Oh, and I will just thow this happy observation into the mix... in case you think this sort of optimization is too revolutionary... http://www.airs.com/blog/archives/120
August 04, 2014
On Sunday, 3 August 2014 at 23:51:30 UTC, Mike Farnsworth wrote:
> This all seems to have a very simple solution, to use something like: expect()
>
> GCC for example has an intrinsic, __builtin_expect() that is used to notify the compiler of a data constraint it can use in optimization for branches.  Why not make something like this a first-class citizen in D (and even expand the concept to more than just branch prediction)?
>
> That way you don't have to hijack the meaning of assert(), but optimizations can be made based on the condition.  __buitin_expect() in gcc usually just figures the expected condition is fulfilled the vast majority of the time, but it could be expanded to make a lack of fulfillment trigger an exception (in non-release mode).  And the compiler is always free to optimize with the assumption the expectation is met.

Indeed, having a new function instead of hijacking assert would seem to be the obvious solution.

That's really interesting about the possibility of conveying probabilistic information to the compiler. Of course, we'd need different functions for constant axioms and probabilistic ones: we could use (for example) assume() for constants and expect() for probabilities.

August 04, 2014
Well, this is not just about branch prediction, but about "let the compiler assume the condition is always true and let it eliminate code that handles other cases".

I /think/ that in C with GCC assume() could be implemented (for release mode, otherwise it's just like assert()) like
  #define assume(cond) if(!(cond)) __builtin_unreachable()
I'm not sure what kind of optimizations GCC does based on "unreachable", though.

However, something like expect() /might/ be a useful addition to the language as well. Maybe as an annotation for if()/else?

Cheers,
Daniel

Am 04.08.2014 01:51, schrieb Mike Farnsworth:
> This all seems to have a very simple solution, to use something like:
> expect()
>
> GCC for example has an intrinsic, __builtin_expect() that is used to
> notify the compiler of a data constraint it can use in optimization for
> branches.  Why not make something like this a first-class citizen in D
> (and even expand the concept to more than just branch prediction)?
>
> That way you don't have to hijack the meaning of assert(), but
> optimizations can be made based on the condition. __buitin_expect() in
> gcc usually just figures the expected condition is fulfilled the vast
> majority of the time, but it could be expanded to make a lack of
> fulfillment trigger an exception (in non-release mode).  And the
> compiler is always free to optimize with the assumption the expectation
> is met.
>
> On Sunday, 3 August 2014 at 19:47:27 UTC, David Bregman wrote:
>> I am creating this thread because I believe the other ones [1,6] have
>> gotten too bogged down in minutiae and the big picture has gotten lost.
>>
>> ...
>>
>> References:
>> [1]: http://forum.dlang.org/thread/lrbpvj$mih$1@digitalmars.com
>> [2]: http://dlang.org/overview.html
>> [3]:
>> http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html
>> [4]: http://blog.regehr.org/archives/213
>> [5]: http://en.wikipedia.org/wiki/Heisenbug
>> [6]: http://forum.dlang.org/thread/jrxrmcmeksxwlyuitzqp@forum.dlang.org

August 04, 2014
On 8/3/14, 3:26 PM, David Bregman wrote:
> On Sunday, 3 August 2014 at 22:15:52 UTC, Andrei Alexandrescu wrote:
>> One related point that has been discussed only a little is the
>> competitive aspect of it all. Generating fast code is of paramount
>> importance for D's survival and thriving in the market. Competition in
>> language design and implementation is acerbic and only getting more
>> cutthroat. In the foreseeable future efficiency will become more
>> important at scale seeing as data is growing and frequency scaling has
>> stalled.
>
> Would you care to address the questions about performance raised in the OP?

I thought I just did.

>> Availing ourselves of a built-in "assert" that has a meaning and
>> informativeness unachievable to e.g. a C/C++ macro is a very important
>> and attractive competitive advantage compared to these and other
>> languages.
>
> Not really, you can redefine the C macro to behave exactly as proposed,
> using compiler specific commands to invoke undefined behavior. Didn't
> you say in the other thread that you tried exactly that?

That might be possible, but one thing I was discussing with Walter (reverse flow analysis) may be more difficult with the traditional definition of assert. Also I'm not sure whether the C and C++ standards require assert to do nothing in NDEBUG builds.

>> Walter has always meant assert the way he discusses it today. Has he
>> (and subsequently he and I) been imprecise in documenting it? Of
>> course, but that just means it's Tuesday.
>>
>> That said, should we proceed carefully about realizing this advantage?
>> Of course; that's a given. But I think it's very important to fully
>> understand the advantages of gaining an edge over the competition.
>
> Please comment on the concerns raised by the OP.

Probably not - there's little motivation to do so. The original post is little else than a self-important rehash of a matter in which everybody has stated their opinion, several times, in an exchange that has long ran its course. Having everyone paste their thoughts once again seems counterproductive.


Andrei

August 04, 2014
On 8/3/14, 3:35 PM, Daniel Gibson wrote:
> Am 04.08.2014 00:15, schrieb Andrei Alexandrescu:
>>
>> That said, should we proceed carefully about realizing this advantage?
>> Of course; that's a given. But I think it's very important to fully
>> understand the advantages of gaining an edge over the competition.
>>
>
> Gaining an edge over the competition?

Yes, as I explained.

> "A new DMD release broke my code in a totally unexpected way and people
> tell me it's because I'm using assert() wrong.

This has been discussed several times, and I agree there's downside. All I want to do is raise awareness of the upside, which is solid but probably less obvious to some. There's no need to trot again in response the downside that has been mentioned many times already.

> I've been using it like this in C/C++/Java/Python and D since forever
> and *now*, after >10years, they changed D's meaning of assert() to
> somehow imply assume() and optimize my safety-checks away.. they pretend
> it was always planned like this but they never got around to tell anyone
> until recently.
> It took me a week to find this freaking bug!"
>
> Doesn't really sound like the kind of advantage over the competition
> that many people would appreciate.
>
> If some rant like this (from Reddit or whatever) is the first impression
> someone gets of D, he's unlikely to ever take a closer look, regardless
> of the many merits the language actually has.

From what I remember there has been good reception (both on reddit and at work) of increased aggressiveness of compiler optimizations.

> (Yes, Johhannes Pfau actually brought a similar  argument somewhere in
> the depth of one of the other threads)
>
> D could still get this kind of edge over the competition by doing these
> kind of optimizations when another keyword (like assume()) is used -
> without breaking any code.

I don't think D will add assume().


Andrei

August 04, 2014
On 8/3/14, 4:01 PM, Timon Gehr wrote:
> On 08/04/2014 12:15 AM, Andrei Alexandrescu wrote:
>>> I suspect it is one of those ideas of Walter's that has consequences
>>> that reach further than anyone foresees..... but that's OK, because it
>>> is fundamentally the correct course of action, it's implications
>>> foreseen and unforeseen will be correct.
>>
>> Agreed.
>
> No, please hold on. Walter is not a supernatural being.

There's something to be said about vision and perspective.

>> Walter has always meant assert the way he discusses it today.
>
> This argument has no merit. Please stop bringing it up.

Actually it does offer value: for a large fragment of the discussion, Walter has been confused that people have a very different understanding of assert than his.


Andrei


August 04, 2014
On 8/3/14, 4:24 PM, Martin Krejcirik wrote:
> On 3.8.2014 21:47, David Bregman wrote:
>> Walter has proposed a change to D's assert function as follows [1]:
>> "The compiler can make use of assert expressions to improve
>> optimization, even in -release mode."
>
> Couldn't this new assert behaviour be introduced as a new optimization
> switch ? Say -Oassert ? It would be off by default and would work both
> in debug and release mode.

That sounds like a good idea for careful introducing of assert-driven optimizations. -- Andrei

August 04, 2014
On 8/3/14, 4:51 PM, Mike Farnsworth wrote:
> This all seems to have a very simple solution, to use something like:
> expect()
>
> GCC for example has an intrinsic, __builtin_expect() that is used to
> notify the compiler of a data constraint it can use in optimization for
> branches.  Why not make something like this a first-class citizen in D
> (and even expand the concept to more than just branch prediction)?

__builtin_expect is actually not that. It still generates code when the expression is false. It simply uses the static assumption to minimize jumps and maximize straight execution for the true case. -- Andrei