C# What JIT Generates? - Folds

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Very interesting!

👍︎︎ 5 👤︎︎ u/asdfasdf666_ 📅︎︎ Sep 05 2020 🗫︎ replies

Your channel is one of the best channels I've come across. It's so easy to understand and you dive right into it. Binge watching all your videos now. Please keep this up!

I'm going to send your LINQ playlist round the office.

👍︎︎ 4 👤︎︎ u/dandandan2 📅︎︎ Sep 05 2020 🗫︎ replies

Nice!

👍︎︎ 2 👤︎︎ u/SmartE03 📅︎︎ Sep 10 2020 🗫︎ replies
Captions
hi everyone and welcome to yet another video called what digit and today we're going to be talking about folds whenever we have a function that contains a constant operation so let's have a function called m now and let's have a variable and let's uh let's do the following let's return two times x so what we're gonna see is we're gonna see an optimization trick where we're gonna just shift left but when we have two times two times x for example what you're gonna see we're gonna be actually shifting by two not by uh one two times so we just folded this into a number called four because what we're gonna do four we're gonna have the same operation so the jit compiler effectively folded these two constants into a single one and that's good because that's an optimization technique so that's that's really cool but you have to be aware that certain faults don't work as you'd expect and you have to be kind of worried about them because otherwise you're not going to get the performance that for example you're aiming for so for example let's have another function called n and let's use this let's return x times two times two so everything just got reversed and as you can see the jit compiler didn't fold these and it just generated two shifts for this two and this two so in the first example we folded stuff and in the second example we didn't so this is this is interesting right and why this happens well first of all the jit compiler will always fall from the left to the right when you have const so the cons have to be on the left hand side not on the right hand side and why is that what's the reason behind this right well the reason behind this is correctness most of the time it could be probably performance because you can imagine that left folding is easier than right folding but i'm gonna bet that it's probably not performance but correctness because what's gonna happen in this example if you have two times two then you have four and you can multiply by that by x and you're done so you can fold these two without any problems but if you have a x which could be a max value of integer for example you're going to overflow this and you're going to multiply this by two so you might not get the same results as in this version here and there could be probably other aspects to correctness that you can imagine by having an end variable here so probably that's the reason why we don't fold uh in this uh in this example here right so the takeaway here is that we have to know what gets folded and why and where it gets folded in order to be able to use these optimization techniques to its false potential so that's that's why all right so that was const folding but now let's transition to something different let's transition to a technique called function folding so let's have a function called division where we're gonna have two arguments x and y and we're just going to return x divided by y but it would be good to check first if x is zero and if it is let's throw a new exception because that's a good thing to do so what we have here is we have a function that generated a bunch of you know assembly instructions a bunch of checks it looks really scary and it looks really complicated but that's not the thing that we should focus now so this function still is really simple and it should be automatically inlined in every single case so let's let's do it because the inlining bit is going to be important here so let's have yet another function that's going to use our division so let's have a function called m1 which will return a division let's divide 10 by 5 for example right so that function got inline but because it got inline the jit will actually see that these two arguments are consts so there's not really not really a reason in to be able to you know to do anything with this function here because we can just divide and we can just divide these two const and return the result and bake that result in into the assembly code and that's going to be it so that's one of the interesting optimization tricks that jit can do for you and it's it's sort of uh like constant unfolding as well because these are the two consts and what we just have to do is we just have to apply this method here we know that y is never going to be zero and that's good so we can fall this into a constant operation but let's not stop there let's continue let's complicate this function a bit and let's see what we're gonna get so let's have a m2 where we're gonna have a single argument and let me return the division of x by five so what we can see here is that we now can apply an optimization trick so we can take this again because remember this is going to be probably inline right so we can take this we know that y is a const so we can just get rid of this and if we have a variable divided by a const we can use a shift trick so this is a shift trick because we don't want to do a division we can do a multiplication with shifts in order to be able to optimize division if we know that we're dividing by a constant number so i've talked about these sort of tricks in my previous video called um what digit integer arithmetic so you can check it out i'm going to leave a link in the description but what you have to remember that it's an optimization trick so again we didn't you know even do even inline this function we just optimized this operation here and everything is okay but it's really crucial to know that it had to be inlineable this function right in order to be able to do that so let's ha let's complicate this even further so now i'm going to have a method called n3 which will take two arguments x and y and what we're gonna do now is we're gonna return a division of x and y this time around and as you can probably tell by the assembly that got generated that this function here is just an inline of the division function they're pretty identical so what happened is if we don't know the arguments they're not const we cannot do any optimizations we cannot do any folding at all so we just have to inline this and be done with it but as you can see if we know something about the arguments of the function if we know that we have certain cons that we can use to be able to optimize our function calls then jit is going to do that automatically and that's really good so that's pretty awesome and you know because these just happen and are called will get faster because of that so now let me show you one of the examples where we would probably expect something to get folded but it's not folded so let's have another function called increment let's take an x as an argument and let's do the following thing let's just increment x a bunch of times and now let's return x so as you can see we just incremented a register four times and that's it what we could have done is we could just take this register and add four to it and just return and that will be perfectly fine so this didn't get folded for some reason and it's probably not because of the optimization tricks that we can do here because it's not really worth the time and increment we're incrementing the same register so that's not going to have any benefit probably so it's just and probably an omission i'm not sure why didn't it didn't get folded but let me show you a different implementation of llvm it's c plus plus and let's see how c plus plus tries to solve this particular problem so let's switch tabs to the compiler explorer and this supports c plus plus amongst other languages but we're now just going to focus on c plus plus and let me do the same thing so i'm going to increment x a bunch of times and let's return x so as you can see we just loaded an effective address to to the register and we just did x plus four and we're gonna just gonna return so yeah this got optimized away but the jit version for some reason didn't so it's something to to remember that not all things are foldable currently maybe that's gonna get patched maybe not we're gonna see but you have to you have to be aware of some of these things not happening and certain things happening or certain things not happening in the way you would like so that's that's another thing to kee to keep in mind if you got value out of this video you know like and subscribe leave a comment if you would like to see something tested in the next video and that's pretty much it for this one so and thank you and see you next time you know bye you
Info
Channel: LevelUp
Views: 1,295
Rating: undefined out of 5
Keywords: C#, csharp, JIT, performance, dotnet, compilers, programming, computer science, tutorial, C# tutorial, clr, clr internals, just in time, just in time compiler
Id: T_Nk9vIDmkQ
Channel Id: undefined
Length: 10min 36sec (636 seconds)
Published: Fri Sep 04 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.