Demystifying the C++ Compiler!

แชร์
ฝัง
  • เผยแพร่เมื่อ 28 พ.ย. 2024

ความคิดเห็น • 85

  • @Nanagos
    @Nanagos 2 หลายเดือนก่อน +49

    "I know this video is long"
    It's only 13 minutes...

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  2 หลายเดือนก่อน +32

      13 minutes with no subway sirfers nowadays is a lot tho 😭

  • @leshommesdupilly
    @leshommesdupilly 2 หลายเดือนก่อน +162

    Pff.. Everyone knows that the compiler isn't magic. The linker is.

    • @shadowlordalpha
      @shadowlordalpha 2 หลายเดือนก่อน +15

      Specifically black magic

    • @leshommesdupilly
      @leshommesdupilly 2 หลายเดือนก่อน +7

      In: source code
      Out: machine code
      Me: Mais qu'est-ce donc cette diablerie ?

    • @ComradeKittenOwO
      @ComradeKittenOwO 2 หลายเดือนก่อน +7

      underated comment
      - LLVM contributor

    • @sachahjkl
      @sachahjkl 2 หลายเดือนก่อน

      Uh, linking is like the simplest step

    • @anon_y_mousse
      @anon_y_mousse 2 หลายเดือนก่อน +1

      @@sachahjkl Not with LTO enabled.

  • @Dom-zy1qy
    @Dom-zy1qy 2 หลายเดือนก่อน +21

    Inspecting the assembly and seeing the optimizations is so interesting sometimes.

    • @MichaelPohoreski
      @MichaelPohoreski 2 หลายเดือนก่อน +3

      Matt Godbolt’s *CompilerExplorer* is a great tool to see how various compilers generate assembly.

  • @Skeffles
    @Skeffles 2 หลายเดือนก่อน +3

    I've been avoiding learning about compilers since I started learning to code, but this gives me that first proper glimpse into them. Fascinating video!

  • @BudgiePanic
    @BudgiePanic 2 หลายเดือนก่อน +22

    Let the compiler cook

  • @skylo706
    @skylo706 หลายเดือนก่อน +1

    Its also interesting to note that at least for some c compilers, it is kind of a gamble if your optimizations work or make it worse. Even if your optimization is an upgrade, it can happen that the compiler will but values into bad spots, like putting a frequently used value way too far away for example. Every time you alter your code, its kind of luck based how your compiler compiles the program. Sometimes it even removes padding for some reason and you won't really notice until it adds up.

  • @Belissimo-T
    @Belissimo-T 2 หลายเดือนก่อน +15

    9:16 I think "CFG" stand for "Control Flow Graph" in this instance

  • @Octal_Covers
    @Octal_Covers 2 หลายเดือนก่อน +8

    I only really use bit shifts in my code when I'm doing other bit math, otherwise I just use division. It's about what makes your code clearer, since the compiler can optimize it

    • @mcxMakerx
      @mcxMakerx 2 หลายเดือนก่อน +1

      Bit manipulation is quite fast and you can store quite a bit of state in a single byte of data.

  • @Harald723
    @Harald723 2 หลายเดือนก่อน +2

    Good timing, I did research on this exact thing like 2 days ago!

  • @sledgex9
    @sledgex9 2 หลายเดือนก่อน +4

    3:30 just to mention that the restrict keyword is not needed in C++ in one particular case. If the two pointers are of incompatible types then C++'s strict aliasing rules apply and the compiler can assume that the pointers don't alias each other.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  2 หลายเดือนก่อน +2

      that sounds like trouble 😂😂😭😭 everyonebe doing pointer aritmetics

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  2 หลายเดือนก่อน +2

      good to know tho

    • @sledgex9
      @sledgex9 2 หลายเดือนก่อน

      @@lowlevelgamedev9330 It turns out that strict aliasing rules exist in C too. So my initial comment might not be so helpful.

  • @SuperLlama88888
    @SuperLlama88888 2 หลายเดือนก่อน +1

    Great explanation! Loved this!

  • @anon_y_mousse
    @anon_y_mousse 2 หลายเดือนก่อน +1

    Well, it should be noted that bitshifting with signed numbers will not always yield the correct results as compared with dividing regardless. However, one of the things that I think people make the mistake of doing over and over again is that of using signed numbers in the first place. And real world testing has proven it well enough for me that unless you're doing ultra simple if/else branches most compilers won't convert it to an equivalent switch statement.
    One of the quotes that keeps being repeated that I really hate is that one from Knuth about optimization. A huge part of optimization is choosing the right algorithms and data structures and it's often the case that you can't just switch them out like going from using a linked list to a dynamic array type. There are real architectural decisions that must be made up front and whether you or Knuth realize it or not, they are most definitely part of optimization. As for LLVM, there are optimizations that it can't do with incomplete information, and the compiler author has to be aware of these limitations to know to provide that information. So merely using LLVM isn't a panacea unless you actually know what you're doing and how to use it.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  2 หลายเดือนก่อน

      hm its kinda wierd the thing that you say about signed and unsigned integers. i haven't seen anyone talk about that. I have also just made a video about switch optimizations and I have tested very big if statements and the compiler optimized it very well. I can even construct a case where a signed if can get a better result. So do you have any examples that I can see? I'm curious. Send them on my discord please 🙏

    • @anon_y_mousse
      @anon_y_mousse 2 หลายเดือนก่อน

      @@lowlevelgamedev9330 I don't use Discord, so I'll have to post an example with CE. The signed versus unsigned part can be seen easily enough by looking at the disassembly for shifting both. Signed integers will generate a sar while unsigned generate a shr. If you don't know x86 assembly, sar copies the "sign bit" down when you shift right while shr zeroes. You can actually exploit this for a branchless abs() function, which I'd wager most compilers will generate with optimizations turned on anyway, but if the compiler can't see your intent, signed shifting is more likely to lead to incorrect results. This brings to mind another issue with signed math, and that's pretty much all division, but more so modulus. Doing modulo math with negative numbers even yields different results in different languages, so be careful there. If YT let's me post a CE link I'll post that later today since I'll have to craft an example from scratch. All the prior examples I have are under NDA.

  • @mgancarzjr
    @mgancarzjr 2 หลายเดือนก่อน +17

    I wonder if anyone has ever optimized out the Monte Carlo estimation of pi.

    • @ungloriusbastards4955
      @ungloriusbastards4955 2 หลายเดือนก่อน +1

      Lol thats an already well documented problem

  • @chickenbobbobba
    @chickenbobbobba 2 หลายเดือนก่อน +5

    some people seem to be relating LLVM to the JVM or other JIT runtimes, but they are completely different. llvm uses AOT compilation while the JVM is JIT, and the intermediary languages also serve different purposes. with LLVM, its there to make compiler development easier, while in the JVM its there to make the conversion from the IR to machine code as fast as possible, to improve the JIT performance.

    • @stefanalecu9532
      @stefanalecu9532 2 หลายเดือนก่อน

      If anything, people should compare LLVM IR to GCC IR (called GIMPLE). Even Pascal p-code back in the old days was accomplishing the same task.

  • @fazin85
    @fazin85 2 หลายเดือนก่อน +1

    I love your videos ❤

  • @carlomaggiolo2180
    @carlomaggiolo2180 2 หลายเดือนก่อน +5

    Is llvm like Java Virtual Machine?
    Or better, the idea is similar of bytecode?

    • @somenameidk5278
      @somenameidk5278 2 หลายเดือนก่อน +6

      kinda? except the bytecode gets further compiled to architecture specific machine code instead of interpreted

    • @abdul4515
      @abdul4515 2 หลายเดือนก่อน +6

      llvm only exists to make it easier for programmers to make compilers. In the olden days, you had to make a compiler that can generate assembly code for EVERY architecture that exists. Now, all you have to do is to make a compiler that can generate llvm IR and then the backend compiles that into machine code native to the target platform. Pretty much all of the new programming languages that are coming out are llvm-based for this reason: it's just a lot easier to do it this way. Hope that made sense.

    • @MrFunny01
      @MrFunny01 2 หลายเดือนก่อน +2

      Java virtual machine as the name implies is a virtual machine/ Java compiler compiles code into java bytecode, which gets interpreted by the program which is written in a native language like C (thus running on directly on the CPU) which is what JVM basically is. So the compile time order is: source code -> bytecode, and runtime order jvm program which runs on the CPU and which takes bytecode as input.
      whereas with LLVM it's source code -> IR, a unique part for every modern language, then a common part which turns IR into the machine code (linker aside). Runtime part is: your program -> cpu. Basically your program directly runs on the

    • @mage3690
      @mage3690 2 หลายเดือนก่อน +1

      LLVMIR is a sort of bytecode, yes. Don't let the acronym LLVM (which stands for Low Level Virtual Machine) fool you, though -- it's not a virtual machine. It translates and compiles that bytecode to a static binary (i.e. an exe) before any code written by the programmer is executed. On the other hand, the JVM simply interprets the bytecode inline and executes them immediately, because it assumes that the bytecode _is_ the program.

    • @carlomaggiolo2180
      @carlomaggiolo2180 2 หลายเดือนก่อน

      @@mage3690 ok yes.
      I Hope my message wasn't wrong, because my English skill isn't so good
      So I retry: I tried to find a similar code to have an idea to understand better why is useful.
      And the first think I had, was the idea the bytecode to have pseudo-compilation to transport your code across the platforms.
      Ok, the JVM wasn't a bad word in this case.
      Thanks you all

  • @matgaw123
    @matgaw123 17 วันที่ผ่านมา

    My opinion is campilers are smarter than humans but if you working with specyfic hardware you could optimized it even More because you know exactly what you are working with and what are bottlenecks for this exact hardware
    And now my question if we are limited by memory speed instead of cpu is there a way to tell compiler it or it will find it out itself
    Because i assume compiler will focus on cpu preformence but if memory bandwidth and latency are bottlenecking it is there a way to tell compiler to use other method but less memory intensive

  • @SimGunther
    @SimGunther 2 หลายเดือนก่อน +2

    99% of the magic happens in the optimizer and boy is it ever a moving target that doesn't rest 😅

  • @arl-t8d
    @arl-t8d 2 หลายเดือนก่อน

    Waiting for LLVM tutorial

  • @RichardLofty
    @RichardLofty 2 หลายเดือนก่อน +1

    Zig doesn't use LLVM now.

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  2 หลายเดือนก่อน +1

      yo it still does, the plan to replace llvm is something that will happen in the very distant future

  • @nzeu725
    @nzeu725 2 หลายเดือนก่อน +2

    Is less than 13 minutes considered long nowadays...

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  2 หลายเดือนก่อน +1

      yes without a subway surfers / minecraft parcour video 😭

    • @nzeu725
      @nzeu725 2 หลายเดือนก่อน

      @@lowlevelgamedev9330 Imma have to stop saying I'm a zoomer, I just don't qualify.

  • @tilted3167
    @tilted3167 2 หลายเดือนก่อน

    How does gcc do it for example if it doesn't use LLVM as a backend?

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  2 หลายเดือนก่อน +1

      I don't know much about gcc but I think it does something similar

    • @sledgex9
      @sledgex9 2 หลายเดือนก่อน +2

      I think it does more or less the same with their own fronted/IR/backends, but these are internal and not intended for external use by other projects. Or more accurately, they make no promise for stable APIs.

    • @abdul4515
      @abdul4515 2 หลายเดือนก่อน +3

      gcc makes assembly code that is native to the platform that you are currently on, you can specify different platforms with the -march and -mcpu compiler flags. gcc then calls the assembler to assemble the assembly code that it just generated. This creates object files (usually one object file per CPP/C file) and then the linker combines those object files into an executable. LLVM-based compilers just spit out llvm IR and then the llvm backend does all the things that LLGD explained in this video.

    • @mage3690
      @mage3690 2 หลายเดือนก่อน +3

      gcc does the same thing, more or less. gcc calls its IR GIMPLE, and you can compile to GIMPLE by simply passing the flag -fdump-tree-gimple to the compiler, and compile from GIMPLE to machine code by way of the -fgimple flag on a file with GIMPLE in it. I'm not remotely knowledgeable enough to even begin to know the differences between gcc and Clang, though. Just because it looks identical on the surface doesn't mean that it's remotely similar underneath the hood.

    • @abdul4515
      @abdul4515 2 หลายเดือนก่อน

      @@mage3690 Guess I was wrong about that. I always thought that gcc worked like oldschool compilers.

  • @kotofyt
    @kotofyt 2 หลายเดือนก่อน

    wrong, people use zig to compile c code only

  • @NullSquad-wk2wt
    @NullSquad-wk2wt 2 หลายเดือนก่อน

    yaayaay

  • @goblinjedly9528
    @goblinjedly9528 2 หลายเดือนก่อน +1

    Blud is talking 'bout preformance and using LLVM LOL. Compile kernel with clang and try to use it LOL

    • @werthorne
      @werthorne 2 หลายเดือนก่อน

      GCC my beloved

    • @stefanalecu9532
      @stefanalecu9532 2 หลายเดือนก่อน +1

      ...what about it? Show up some numbers ;)

    • @treelibrarian7618
      @treelibrarian7618 2 หลายเดือนก่อน

      @@werthorne at least clang will use cmov's when appropriate

  • @slava6105
    @slava6105 2 หลายเดือนก่อน

    But... C-- is already an IR for GHC...
    7:30 ok, that's another C--.

    • @anon_y_mousse
      @anon_y_mousse 2 หลายเดือนก่อน

      Multiple people have had the thought to name a language C--. One is used on embedded platforms and has existed for a couple of decades at least.

  • @r9gaming279
    @r9gaming279 2 หลายเดือนก่อน

    Please give me roadmap to learn cpp for game development

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  2 หลายเดือนก่อน +1

      yo I actually have a video for that
      th-cam.com/video/sX52Hak4SaY/w-d-xo.html
      and you can also find help on my discord server (link in video description)

    • @r9gaming279
      @r9gaming279 2 หลายเดือนก่อน

      @@lowlevelgamedev9330 thank sir

  • @drevcronsole
    @drevcronsole 2 หลายเดือนก่อน +5

    petition to make python a compiled language

    • @SimGunther
      @SimGunther 2 หลายเดือนก่อน

      Wish you luck making a compiled language that harkens back to python :)

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  2 หลายเดือนก่อน +1

      you can actually compile python to an exe with an external tool

    • @drevcronsole
      @drevcronsole 2 หลายเดือนก่อน

      @@lowlevelgamedev9330 new thing known, IQ increased. Monkey brain happy

    • @treelibrarian7618
      @treelibrarian7618 2 หลายเดือนก่อน

      and then there's mojo: python syntax with optional typing that unlocks the ability to scale across threads, vectorization, and GPU/NPU hardware. from the creator of LLVM.

  • @coderflowerdev
    @coderflowerdev 2 หลายเดือนก่อน +9

    24 seconds ago, no views, yay first comment

    • @lowlevelgamedev9330
      @lowlevelgamedev9330  2 หลายเดือนก่อน +1

      still no views according to youtube 2 comments and one like let's go 😂

    • @mgancarzjr
      @mgancarzjr 2 หลายเดือนก่อน +1

      bro fell off

  • @_sztywny
    @_sztywny 2 หลายเดือนก่อน

    hi

  • @radosmirkovic8371
    @radosmirkovic8371 2 หลายเดือนก่อน +1

    So llvm has stolen idea from jvm and tweaked it.

    • @chickenbobbobba
      @chickenbobbobba 2 หลายเดือนก่อน +5

      no, llvm uses AOT compilation while the JVM is JIT. their purposes are also completely different. the intermediary language in llvm is to make compiler development easier, while in the jvm its there to make the conversion from the IR to machine code as fast as possible, to improve the JIT performance.

    • @radosmirkovic8371
      @radosmirkovic8371 2 หลายเดือนก่อน

      @@chickenbobbobba I was talking about idea not about implementation. Yes, jvm is jit and GraaalVM allows aot compilation. But idea is still there. So c and c++ are in a way being java-like.

    • @chickenbobbobba
      @chickenbobbobba 2 หลายเดือนก่อน +2

      @@radosmirkovic8371 well no, the idea is exactly the exact thing that makes them different. javas IL is present at runtime while C's is not. and again, LLVM only uses it to make it easier to write a compiler, while the JVM uses it to aid with making cross platform but still performant code.

    • @radosmirkovic8371
      @radosmirkovic8371 2 หลายเดือนก่อน

      @@chickenbobbobba Thanks for clarification.

    • @chickenbobbobba
      @chickenbobbobba 2 หลายเดือนก่อน

      @@radosmirkovic8371 also the idea of an intermediary language is not a new one, they existed well before java became a thing.

  • @zxcaaq
    @zxcaaq 2 หลายเดือนก่อน +1

    what is this crap

  • @alihene2225
    @alihene2225 2 หลายเดือนก่อน

    Early on this one yay