Your New Mental Model of constexpr - Jason Turner - CppCon 2021

Sdílet
Vložit
  • čas přidán 10. 01. 2022
  • cppcon.org/
    github.com/CppCon/CppCon2021
    ---
    In my experience as a trainer, CZcamsr, and speaker, I find that many people have a mistaken impression of what constexpr is and for what it is suited. I see people over-complicate constexpr by conflating it with meta programming and template-related topics. Students will often fail to recognize where and when constexpr could be used. Experts will get concerned about the "contract" you are making with the user of your library by marking functions as constexpr.
    In this talk, I will present a mental model for how you should consider constexpr. I will explain what constexpr is (less mechanically and more metaphorically), give practical applications for constexpr, and help you figure out where constexpr fits into your application or library.
    In the most straightforward sense, constexpr is moving work from runtime to compile-time. This mental model that I will present will ask, "what work would you rather do at compile-time?" We will find this answer by looking at constexpr as a continuum. On one end of the continuum is the use case of moving a runtime fixed-size vector into a compile-time fixed-size constexpr array, and on the far end is executing your entire program at compile-time and simply outputting the results at runtime.
    ---
    Jason Turner
    Host of C++Weekly / jasonturner-lefticus , Co-host of CppCast cppcast.com, Co-creator and maintainer of the embedded scripting language for C++, ChaiScript chaiscript.com, and author and curator of the forkable coding standards document cppbestpractices.com.
    I'm available for contracting and onsite training.
    ---
    Videos Filmed & Edited by Bash Films: www.BashFilms.com
    CZcams Channel Managed by Digital Medium Ltd events.digital-medium.co.uk
    *--*
  • Věda a technologie

Komentáře • 67

  • @OperationDarkside
    @OperationDarkside Před 2 lety +59

    Great talk. I always enjoy Jason's presentations, but I'm still waiting for constexpr Doom :-p

    • @yash1152
      @yash1152 Před rokem +1

      oh wow, didn't read the complete title before - hey, it's again jason turner

  • @nothke
    @nothke Před 2 lety +3

    Yesss, new Jason talk! I was looking forward to this the whole year

  • @peregrin71
    @peregrin71 Před 2 lety +12

    In the end using constexpr (if at all applicable) or not boils down to a basic standard software engineering questions : do you trade memory for speed. I mention this because the compile time generated data tables may be bigger then the runtime code needed to generate those tables and this might be an issue on smaller systems.

    • @kamilziemian995
      @kamilziemian995 Před rokem

      Can you give me some guidance, when I can read more about this topic of memory usage of constexpr?

    • @kice
      @kice Před rokem +1

      @@kamilziemian995 constexpr is evaluated at compile time, meaning there is NO overhead both for speed and space. However, if you need to store nontrivial value, such as a string, some collection of data, that you might need to allocate more memory than actually needed in order to evaluate at compile time.
      Pep said that this kind of tradeoff might cause problems for constraint environment, since it mostly likely inflates the input data as constexpr results (but I 70% disagree), and you are not able to release (technically you should not) the memory allocated by constexpr.

    • @Girugi
      @Girugi Před rokem

      That is a bit naive/too simple and general. Often not really true... Your "may" in that sentence is very very important.
      Constexpr can give both speed and save memory at the same time. Preprocessing data into more compact representation is also possible. Like, let's say you inline a text file and parse it. Like, a json file often/always takes less data in a binary representation than in it's text form. Especially if you also consider that the parsing itself will likely take up memory and have the raw text in memory at the same time for some proportion of the time. Which you don't need when it is preparsed. Just as an example. Of course you can parse it into your own binary file in a separate step and load that at runtime too, but that has limits as well, and does still takes extra memory while loading.
      Or very commonly, const hash strings. The hash takes less data than the string.
      And in most cases I would actually claim that the constexpr takes about the same data before and after, but there are cases where it takes more and cases where it takes less. But as always, making general claims is in general not good.

  • @joonasmakinen4807
    @joonasmakinen4807 Před 2 lety +14

    Wow, thank you very much for this presentation! I sense this is very very important for the performance limited embedded systems and their optimizations!

    • @CppCon
      @CppCon  Před 2 lety +1

      Glad it was helpful!

  • @adammitchell55
    @adammitchell55 Před 2 lety +7

    I always enjoy your constexpr talks Jason. It makes me reconsider what work could reasonably be done at compile time in my work. I've been pushing to constexpr more over the last year or so. Also I got the Back to the Future joke. :)

  • @nivo6379
    @nivo6379 Před 2 lety +1

    Excellent talk, Jason!

  • @fromgermany271
    @fromgermany271 Před 2 lety +4

    constexpr example I did:
    for a given time interval, with a given clock speed, find the best fitting clock divider/top count value for the timer of an Atmel chip (Arduino) and into just 6 instructions to fill the 3 register bytes used.

  • @aloluk
    @aloluk Před 2 lety +4

    Jason, great presenter as always. Thanks also for your CZcams channel!

  • @mahdies9620
    @mahdies9620 Před 2 lety +1

    such good talk, thank you Jason

  • @dexus340
    @dexus340 Před 2 lety

    WOOH! YEAH BABY! THAT'S WHO I'VE BEEN WAITING FOR, CONSTEXPR IS WHAT IT'S ALL ABOUT.

  • @ixiwildflowerixi
    @ixiwildflowerixi Před 2 lety +14

    In my experience, an audience that doesn't have a question doesn't usually mean they're an expert in the topic at hand, but rather that they haven't understood anywhere near enough to even consider considering questions.

  • @kamilziemian995
    @kamilziemian995 Před rokem

    This talk was very hard to follow, but I glad that I did it.

  • @moretromain
    @moretromain Před 2 lety +5

    Thank you Jason and cppcon for this! Everytime I watch one of Jason's talk, I start with skepticism, because the headline doesn't appeal much and the beginning sounds like old news, but then I keep watching because it's cppcon, it means more than that and I know better about Jason, so I wait for the moment in his talk where I'll flip and go like "ok now we're talking", then it comes, time to share! At that point I start sending links to colleagues and friends, and we start discussing about the real deal that this talk is about, and we start deconstructing the bits and pieces of what has just been presented to us, just so we can come to the same conclusions by our own, and appreciate even more all the outcomes of it, and that's is the really cool part. Thank you Jason and everyone involved for allowing us to grow and contribute through what you share to the community, much appreciated!

    • @rezNezami
      @rezNezami Před rokem

      Wow. You do have a great positive way of turning things. I guess if you watch a light bulb long enough you'd discover more that the light emitting! Core message of a presentation must come clear and without a need for that wow moment patiently!!

  • @Erarnitox
    @Erarnitox Před rokem +1

    29:00 also you don't always want to have everything possible at compile time. When working on bigger projects compiles might take hours and heavy use of constexpr and templates do add to that and make debugging more annoying. Also this can effectively DOS your build server. And i these cases where there is no real time performance requirement or any other hard run time performance requirements I think it can make sense to also do things at runtime, even though they would be possible at compile time.
    Also as jason mentioned: compile time computation often produces a bigger binary, because it has to store the computation results somehow (can also make the binary smaller, so this is not a rule). But if you have a storage medium limitation, you sometimes have to generate things at runtime. I think the game KKrieger is an amazing and extreme example of this.
    So it is always a question of what you value most. And C++ always is about giving the user the option/power. So having the compiler decide what should be constexpr would go against one principle of C++ that make many people love the language so much.

  • @Voltra_
    @Voltra_ Před 2 lety +2

    My favorite part of every cppcon: constexpr

  • @VioletGiraffe
    @VioletGiraffe Před 2 lety +1

    I'm writing a toy database engine and I'm trying to do as much as I can at compile time. I've been at it off an on for more than two years, almost have a working proof of concept now, and I have very little runtime code. You can do a lot at compile time if you design for it from scratch, and the most difficult problem I've had was serializing and de-serializing (because de-serialization from storage happens at runtime by definition, yet it must produce compile-time-constant results so that further processing of the results can happen at compile time again). Had to redesign this part three times to avoid insane compiler recursion depth and code bloat.

  • @jhk578
    @jhk578 Před 2 lety +5

    I think constexpr is about dealing with static information. Static information is information that is known at compile time. If initial information, data is static we can process it as much as we want in compile time. So like presentation here, many resource is known at compile time already, we can process it as much as we want(of course there might be limitation in current C++, but it is not about fundamental limitation). On the other hand, dynamic information, which is information that is created in runtime(like user input data), can not be handled in constexpr context. Trade off might be memory space and compile time.

  • @intvnut
    @intvnut Před rokem

    I remember writing a font scaler in GW-BASIC on a Tandy 1000 back in the early 1990s that scaled up the CGA font in roughly the same way that Jason's approximation of hq2x ends up doing. I believe the actual hq2x algorithm, however, is more sophisticated, since it deals with color. I was only working with 1bpp CGA font bitmaps.
    And the result looked pretty much identical to the smoothed font in Jason's preso. It was a fun blast from the past for me. 😀
    And in case anyone wonders, I'm referring to the _original_ Tandy 1000, with no suffix letters. I had an add-in card to take it from 128K to 640K. It was like a "Super PCjr" in many ways.

  • @NoNameAtAll2
    @NoNameAtAll2 Před 2 lety

    26:17 will that talk be linked when it will be released?

  • @pllee4
    @pllee4 Před 9 měsíci +2

    This talk has inspired me to code the presentation slide! I have written an article with the title "Code Your Presentation Slides as an Executable Program" on Medium.

  • @JarenKurkoff
    @JarenKurkoff Před rokem

    This was a really fun and entertaining talk. I think compile time regular expression compilation is quite possibly *the* most clever use of constexpr I have ever seen. That being said, though, despite his compile time ARM emulator being possibly just for fun, I do have to wonder at what point are you, the programmer, treating compile-time *as* runtime, and whether or not that makes it worth it to even use constexpr in the first place if you are treating compile-time as runtime.

    • @RobBCactive
      @RobBCactive Před 5 měsíci

      Once I wrote C which changed some complicated algorithm code initialisation with debug into generating the actual C for storing the data in run time tables and then simply including that in itself if it wasn't in source generation mode. I had been diff-ing output to ensure correctness so it was a small step.
      This made run time far simpler using known correct results from debugged prior runs and proved actually much faster than mmap-ing the pre-calculated data from file which was slightly harder to implement, while the C gen code made it self-documenting. It was modifiable too, as if including generated code was off, then the build tables & code generation would be run instead.
      An advantage was compile time was accelerated too 😊😊
      I can imagine it would have caused gray hairs if managers had heard of any plan to do that, while I did it as an experiment having had the insight and had it working in one afternoon because it was so simple.
      In this case it was natural evolution of the program as I developed it, like cache-ing results and freezing in the analysis that lead to algorithmic improvement. So really you could sometimes feedback runtime into compile time too, with some very interesting trade offs. 🤔🤔

  • @tomekczajka
    @tomekczajka Před 2 lety

    Fun talk, but what's the "old" mental model of constexpr then? I thought that constexpr was always about doing things at compile time.

  • @samuelsrikar2870
    @samuelsrikar2870 Před 2 lety

    Font scaling example is cool.

  • @fromgermany271
    @fromgermany271 Před 2 lety +6

    Love it!
    Jason running PPT on C64.
    At least according to the fonts.
    But content is key! 👍🏻👍🏻👍🏻
    PS.: i swear, I wrote this after seeing his first „slide“

    • @cppweekly
      @cppweekly Před 2 lety +2

      Not full powerpoint, of course :D

    • @richardvonlehe4581
      @richardvonlehe4581 Před 2 lety +1

      I found I spent too much energy trying to read the slides with that font.

  • @mEm__96
    @mEm__96 Před 2 lety +1

    I was experimenting with some VERY simple constexpr trials, just to see practically how a function marked constexpr might be evaluated at compile time.
    Here is the very first lines I had written:
    ```
    constexpr int summ(const int& val) {
    return val + 1;
    }
    int main()
    {
    constexpr int val = 1;
    auto res = summ(val);
    return res;
    }
    ```
    Well, I noticed that this works fine using GCC (i.e. mov DWORD PTR [rbp-4], 2 ).
    On the other hand, if using CLANG (even trunk), it does make an explicit call to summ().
    EDIT: I found out that CLANG does work by changing the line "auto res = summ(val);" to "constexpr auto res = summ(val);"
    Why then does GCC work even without the constexpr keyword in front of "auto res = summ(val);" ?

    • @bjornsundin5820
      @bjornsundin5820 Před 2 lety

      GCC moves it to compile time even without the constexpr keyword because it can do that as an optimization without changing the behavior of the program. Compilers may do a lot they don't need to do to speed up the runtime of programs, especially at higher optimization levels. If you write a for loop that sums up all numbers between 1-100, GCC will most likely just compute that at compile time because it can. Or if you write a function that sums all numbers between 1 to an integer parameter n using a for loop, it might just replace that with the formula n(n+1)/2.

    • @VioletGiraffe
      @VioletGiraffe Před 2 lety

      This can be annoying, and it's the whole reason consteval keyword was added. As Jason mentioned, a constexpr function function is one that might be executed at compile time, but it's not required to.

  • @DamianReloaded
    @DamianReloaded Před 2 lety +1

    I wonder why would I not want the compiler to constexpr everything by default? Is it for backwards compatibility to avoid having things written in an old way optimized out?

    • @SianaGearz
      @SianaGearz Před 2 lety

      I don't think compatibility is that much of a concern. You can just emit a function and have the linker then deal with it in case it isn't used by someone. If it's static or inline and nobody tries to take a pointer to it in a given module then it doesn't even need to be emitted. Compilers are fundamentally capable and sometimes optimise out both loops (including timing ones, there are ways to deal with that though - 'volatile' or 'asm'), and function invocations.
      Problem one is that trying to evaluate EVERY possible expression at compile time can be spectacularly slow, given the compilers don't all have a compiler available to them at compile time, which, i know, sounds absurd, but they often output either just an intermediate representation that ends up getting compiled by the linker - another program - or assembly, and needs to be assembled and THEN linked by an external process, what you want is specifically a JIT, and they don't generally have one at hand, so they will end up interpreting it from the slow AST. If they were to have a JIT available (LLVM, maybe DMC), then guessing whether JIT is actually faster is another difficulty.
      Problem two is that this can cause an increase or loss of precise control over binary size, while C++ targets everything from ATTiny12 to an Epyc or Xeon and a lot of weird things in between. Obviously you don't get STL on an ATTiny but as far as compiler/language features, they're all there! Output of a constexpr can be of arbitrary size.

  • @diconicabastion5790
    @diconicabastion5790 Před 2 lety +4

    So basically I can have my game engine run during compile time. Pretty sure that would be a really bad use of this but I get the point.
    Handy if I want to say generate some table, data, patterns, expression handlers, or other code that I didn't want to have to do every-time the program starts.

  • @user-uk3lr3el8h
    @user-uk3lr3el8h Před 4 měsíci

    Far too many :
    This works only for small (academical) programs,
    but does not work for very, very big programs,
    because:
    if you don't know the type, it's very hard to make safe changes.

  • @AG-ld6rv
    @AG-ld6rv Před 2 lety +1

    He talks at normal speed if you want the video at 1.5x. 1.75x is doable although it's a little fast. Had to slow down for the Q&A though.

  • @yixingliu6673
    @yixingliu6673 Před 2 lety +1

    How're the slides made? I'm a fan of the text editor style.

    • @UKMonkey
      @UKMonkey Před 2 lety +2

      How to say you didn't watch the presentation - without saying you didn't watch it.

    • @malborboss
      @malborboss Před měsícem

      23:36

  • @MrGencyExit64
    @MrGencyExit64 Před 2 lety +4

    I both love and hate constexpr. As a game modder, I don't want any of a game evaluated at compile time and hidden from me, but as a game modder, I want as much of my own code not adding performance overhead at runtime :)

  • @NoNameAtAll2
    @NoNameAtAll2 Před 2 lety

    46:55 this feels like memoization :)

  • @yash1152
    @yash1152 Před rokem +1

    1:54 summary of constexpr
    7:26 "i'm'n a room full of constexperts" oh loll, nice play
    9:41 [equivalent to] a macro: #define

  • @kamilziemian995
    @kamilziemian995 Před rokem

    Jason Turner is some kind of C++ superman. And constexpert.

  • @wanderer7480
    @wanderer7480 Před 2 lety

    Does anybody have the link for the presentation he talked about at 51:28?

    • @Ryan1729
      @Ryan1729 Před 2 lety

      I was interested in that one too. I believe it's this one: czcams.com/video/OcyAmlTZfgg/video.html

  • @LaurentLaborde
    @LaurentLaborde Před rokem

    we can do petscii. Ho ho I know where this is going, you're gonna say that the whole slide is constexpr, right ?

  • @LucasHartmann
    @LucasHartmann Před 2 lety +2

    To me constexpr feels like the next "auto" (local variable marker) and "register." The compilers will eventually get smart enough to figure it on their own.

  • @mark_fi
    @mark_fi Před 2 lety

    The font at 00:08 made me misread the word Mental.

  • @iceman8075
    @iceman8075 Před 2 lety +1

    nice

  • @muhammadharris4470
    @muhammadharris4470 Před 2 lety +2

    Did you just replace ppt with c++ console. cool. Guess ppt is overrated. Love the font and slide transitions

    • @ska4dragons
      @ska4dragons Před 2 lety

      I'd like to see the code for that.

  • @qm3ster
    @qm3ster Před 2 lety +1

    Need 47:47 in HD

  • @jamesschmames6416
    @jamesschmames6416 Před rokem +1

    This guy perfectly exemplifies the overzealous "clever" C++ programmer. I have a hammer so everything looks like a nail. Or in this case I have a sledge hammer and I want to hang a picture on a wall.
    The only place that excessive use of constexpr to move compute to compile is on a program that gets loaded up and then discarded over and over and over. Anything you can compile can be done at program load. On a long running process do you really care if it takes a few extra seconds to start up?
    Maybe it makes slightly more sense if you compile on a 128 core monster to be run on some ancient anemic hardware, but how often does that really apply.
    This is "I've got a solution to a problem" virtually no one is asking for.

    • @n0ame1u1
      @n0ame1u1 Před rokem

      There are plenty of programs that get loaded and then discarded quickly, like most command-line utilities

    • @Knirin
      @Knirin Před 3 měsíci

      @@n0ame1u1Yeah, but none of them need constexpr. Most of the stuff you would use constexpr for was traditionally done translating a small dsl into C or C++ and then including that code. Those DSLs were usually more readable for their scenarios than constexpr is.

  • @xephael3485
    @xephael3485 Před rokem

    The podium looks like a toilet tank...

  • @PaulSkeptic
    @PaulSkeptic Před 2 lety +2

    Of all the hard to read fonts that exist, this is one of the most unreadable. Comis Sans would be a world of improvement in this case honestly.