WEBVTT

1
00:00:00.040 --> 00:00:04.000
<v Speaker 1>Hey, everyone, ready for another deep dive Today. We're going

2
00:00:04.080 --> 00:00:05.519
<v Speaker 1>to look at assembly language.

3
00:00:05.639 --> 00:00:09.240
<v Speaker 2>Ooh, assembly language going low level.

4
00:00:09.400 --> 00:00:13.599
<v Speaker 1>Yeah, but you know, assembly language can seem a little

5
00:00:13.640 --> 00:00:15.560
<v Speaker 1>bit intimidating, a little bit like a you know, a

6
00:00:15.599 --> 00:00:18.519
<v Speaker 1>relic of the past for a lot of programmers. Yeah,

7
00:00:18.559 --> 00:00:21.480
<v Speaker 1>but I think that understanding it, even if you're not

8
00:00:21.519 --> 00:00:24.839
<v Speaker 1>writing it directly, can make you a much much better

9
00:00:24.879 --> 00:00:27.120
<v Speaker 1>programmer in any language. What do you think?

10
00:00:27.199 --> 00:00:30.719
<v Speaker 2>I completely agree. I think it's kind of like knowing

11
00:00:30.719 --> 00:00:33.759
<v Speaker 2>how your car works. You know, you don't need to

12
00:00:33.759 --> 00:00:36.079
<v Speaker 2>be a mechanic to drive, right, right, Yeah, but if

13
00:00:36.119 --> 00:00:37.799
<v Speaker 2>you know how your car works, you're probably going to

14
00:00:37.840 --> 00:00:38.560
<v Speaker 2>be a better driver.

15
00:00:38.759 --> 00:00:41.399
<v Speaker 1>Right. You'll know when something's wrong, Yeah, exactly. Yeah, you'll

16
00:00:41.399 --> 00:00:43.399
<v Speaker 1>be able to maybe fix it yourself, or you'll know

17
00:00:43.479 --> 00:00:44.600
<v Speaker 1>when to take it to the shop.

18
00:00:44.679 --> 00:00:45.280
<v Speaker 2>Absolutely.

19
00:00:45.439 --> 00:00:48.880
<v Speaker 1>So to guide us on this journey today, we got

20
00:00:48.920 --> 00:00:52.799
<v Speaker 1>some excerpts from the book Thinking Low Level Writing High

21
00:00:52.880 --> 00:00:56.119
<v Speaker 1>Level Write Great Code. And this book it's really interesting.

22
00:00:56.159 --> 00:01:01.600
<v Speaker 1>It really busts some myths about compiled and about optimization,

23
00:01:01.880 --> 00:01:05.120
<v Speaker 1>and it gives you some really actionable insights that I

24
00:01:05.120 --> 00:01:06.959
<v Speaker 1>think can level up your coding game.

25
00:01:07.200 --> 00:01:10.920
<v Speaker 2>Yeah. I think one of the mythsetbusts is that compilers

26
00:01:10.959 --> 00:01:13.439
<v Speaker 2>are so good these days that there's really no point

27
00:01:13.519 --> 00:01:17.799
<v Speaker 2>in learning assembly language, right, which I think this book

28
00:01:17.879 --> 00:01:19.640
<v Speaker 2>kind of proves that that's not true.

29
00:01:20.000 --> 00:01:23.480
<v Speaker 1>So why why should we be skeptical of let's say,

30
00:01:23.560 --> 00:01:27.400
<v Speaker 1>like compiler benchmarks, right, Like, we see benchmarks all the time.

31
00:01:27.439 --> 00:01:29.760
<v Speaker 1>This compiler's faster, this one's more efficient.

32
00:01:29.879 --> 00:01:32.400
<v Speaker 2>Well, you got to think about who is making those benchmarks.

33
00:01:32.480 --> 00:01:36.040
<v Speaker 2>Usually it's the compiler vendors themselves, so they're going to

34
00:01:36.120 --> 00:01:38.799
<v Speaker 2>write code that makes their compiler look good.

35
00:01:38.840 --> 00:01:40.719
<v Speaker 1>So it's like if you were, you know, designing a

36
00:01:40.799 --> 00:01:44.159
<v Speaker 1>racetrack for your specific car. Yeah, exactly, it might not

37
00:01:45.040 --> 00:01:47.519
<v Speaker 1>be a fair comparison to other cars. Absolutely, so the

38
00:01:47.519 --> 00:01:50.120
<v Speaker 1>results might not reflect like real world performance.

39
00:01:50.319 --> 00:01:51.159
<v Speaker 2>Yeah totally.

40
00:01:51.200 --> 00:01:53.680
<v Speaker 1>And that's where I think assembly language can really shine

41
00:01:53.760 --> 00:01:55.519
<v Speaker 1>because it can help you. You know, if you can

42
00:01:55.640 --> 00:01:58.680
<v Speaker 1>understand how your code is running at that machine level,

43
00:01:59.560 --> 00:02:02.159
<v Speaker 1>you can make spot Bottle likes yourself. Yeah, you can

44
00:02:02.200 --> 00:02:05.519
<v Speaker 1>write more efficient code even if the compiler is not

45
00:02:05.560 --> 00:02:08.439
<v Speaker 1>doing everything perfectly for you. So it's about developing that

46
00:02:08.479 --> 00:02:11.520
<v Speaker 1>low level intuition. Absolutely, even if we never write assembly

47
00:02:11.560 --> 00:02:13.479
<v Speaker 1>code ourselves, we could still.

48
00:02:13.319 --> 00:02:16.240
<v Speaker 2>Benefit from that totally, and you realize pretty quickly that

49
00:02:16.439 --> 00:02:19.319
<v Speaker 2>even a simple statement that you write in a high

50
00:02:19.400 --> 00:02:24.000
<v Speaker 2>level language, like just a simple calculation, can actually end

51
00:02:24.120 --> 00:02:27.280
<v Speaker 2>up being multiple machine instructions when it gets translated down

52
00:02:27.319 --> 00:02:30.039
<v Speaker 2>to assembly. For example, there's this example in the book,

53
00:02:30.120 --> 00:02:34.000
<v Speaker 2>a visual Beasic statement. It says profits is sales cost

54
00:02:34.360 --> 00:02:36.240
<v Speaker 2>or goods overhead commissions.

55
00:02:36.599 --> 00:02:38.919
<v Speaker 1>Yeah, I mean that's basic math. You'd think that would

56
00:02:38.960 --> 00:02:40.879
<v Speaker 1>be one instruction, one instruction.

57
00:02:41.039 --> 00:02:43.360
<v Speaker 2>But at the machine level, at least on the eighty

58
00:02:43.360 --> 00:02:47.199
<v Speaker 2>by eighty six architecture, the CPU can only work with

59
00:02:47.280 --> 00:02:50.000
<v Speaker 2>like two operads at a time, so you're going to

60
00:02:50.080 --> 00:02:53.319
<v Speaker 2>have to have multiple subtract instructions in assembly to actually

61
00:02:53.360 --> 00:02:54.120
<v Speaker 2>carry that out.

62
00:02:54.520 --> 00:02:56.159
<v Speaker 1>So even though it looks really simple in our high

63
00:02:56.199 --> 00:02:59.159
<v Speaker 1>level code, it can be a whole process.

64
00:02:59.159 --> 00:03:01.159
<v Speaker 2>It can be a whole dancer team, yeah, for the CPO.

65
00:03:01.319 --> 00:03:05.000
<v Speaker 1>Yeah yeah. So, speaking of the eighty by eighty six architecture,

66
00:03:05.439 --> 00:03:07.800
<v Speaker 1>what are some maybe some mind blowing things that you've

67
00:03:07.840 --> 00:03:09.319
<v Speaker 1>learned about eighty by eighty six.

68
00:03:10.199 --> 00:03:12.639
<v Speaker 2>One thing that might surprise people is that those familiar

69
00:03:12.680 --> 00:03:17.240
<v Speaker 2>eighty by eighty six registers like EAX, EBX, ECX.

70
00:03:16.719 --> 00:03:18.199
<v Speaker 1>Right, the general purpose registers.

71
00:03:18.319 --> 00:03:20.800
<v Speaker 2>Yeah, those aren't actually all separate entities.

72
00:03:20.879 --> 00:03:23.360
<v Speaker 1>I always imagine them as like separate little like, you know,

73
00:03:23.800 --> 00:03:25.879
<v Speaker 1>little boxes, little boxes in the CPU.

74
00:03:26.039 --> 00:03:28.840
<v Speaker 2>Yeah, yeah, but they a lot of them overlap. So

75
00:03:29.080 --> 00:03:32.479
<v Speaker 2>the lower sixteen bits of EAX, that thirty two bit

76
00:03:32.599 --> 00:03:35.840
<v Speaker 2>register that can be accessed as a sixteen bit register

77
00:03:35.960 --> 00:03:36.719
<v Speaker 2>called AX.

78
00:03:36.840 --> 00:03:37.039
<v Speaker 1>Oh.

79
00:03:37.120 --> 00:03:40.000
<v Speaker 2>Interesting, and then AX that's divided up into two eight

80
00:03:40.039 --> 00:03:41.879
<v Speaker 2>bit registers ah and al.

81
00:03:42.240 --> 00:03:46.400
<v Speaker 1>So it's like those registers are like a Russian nesting doll. Yes, yeah,

82
00:03:46.560 --> 00:03:49.280
<v Speaker 1>you know, registers within registers exactly. You got to be

83
00:03:49.319 --> 00:03:51.840
<v Speaker 1>mindful I guess of how changing one register might affect

84
00:03:51.919 --> 00:03:52.319
<v Speaker 1>other ones.

85
00:03:52.439 --> 00:03:52.639
<v Speaker 2>Yeah.

86
00:03:52.919 --> 00:03:55.840
<v Speaker 1>Yeah, it's a historical design decision they made to maintain

87
00:03:55.879 --> 00:03:59.479
<v Speaker 1>backward compatibility, right, right, But it's really interesting. It's something

88
00:03:59.520 --> 00:04:03.240
<v Speaker 1>you don't think about when you're writing high level code. Yeah.

89
00:04:03.919 --> 00:04:06.960
<v Speaker 1>What other kind of low level secrets does this book reveal?

90
00:04:07.319 --> 00:04:11.240
<v Speaker 2>Another one is index addressing mode, okay, which is how

91
00:04:11.280 --> 00:04:15.479
<v Speaker 2>you access array elements. Oh yeah, and how that works

92
00:04:15.599 --> 00:04:18.199
<v Speaker 2>can really influence how you structure your code.

93
00:04:18.399 --> 00:04:20.519
<v Speaker 1>So can you give us a quick rundown of what

94
00:04:20.560 --> 00:04:21.839
<v Speaker 1>indexed addressing mode is?

95
00:04:22.079 --> 00:04:25.439
<v Speaker 2>Imagine you have an array of numbers stored in memory, right,

96
00:04:25.879 --> 00:04:28.079
<v Speaker 2>so each element of that array is going to be

97
00:04:28.120 --> 00:04:32.120
<v Speaker 2>at a specific address in memory. Indexed addressing lets you

98
00:04:32.240 --> 00:04:35.480
<v Speaker 2>calculate the address of a specific element by adding an

99
00:04:35.519 --> 00:04:38.120
<v Speaker 2>offset to the base address of that array.

100
00:04:38.560 --> 00:04:40.439
<v Speaker 1>So like, if I want to access the fifth element

101
00:04:40.480 --> 00:04:42.319
<v Speaker 1>of an array, I add an offset of four.

102
00:04:42.480 --> 00:04:45.360
<v Speaker 2>Yeah, if it's zero based indexing, exactly, you've got four

103
00:04:45.439 --> 00:04:47.759
<v Speaker 2>to the beginning on its address. Yeah, and that gets

104
00:04:47.800 --> 00:04:48.720
<v Speaker 2>you to the fifth element.

105
00:04:48.800 --> 00:04:52.480
<v Speaker 1>Wow, it's amazing how much is happening under the hood

106
00:04:52.759 --> 00:04:54.600
<v Speaker 1>that we don't really think about at the high level.

107
00:04:55.079 --> 00:04:58.560
<v Speaker 1>So we've talked about how compilers. You know, they handle

108
00:04:58.600 --> 00:05:03.199
<v Speaker 1>a lot for us, but they're not perfect. Yeah. What

109
00:05:03.279 --> 00:05:07.040
<v Speaker 1>are some things that compilers struggle with, especially when it

110
00:05:07.040 --> 00:05:07.920
<v Speaker 1>comes to optimization.

111
00:05:08.160 --> 00:05:09.959
<v Speaker 2>Well, one of the things they struggle with is they

112
00:05:10.000 --> 00:05:12.399
<v Speaker 2>only have a limited amount of time to analyze and

113
00:05:12.519 --> 00:05:14.000
<v Speaker 2>optimize your code.

114
00:05:14.199 --> 00:05:15.439
<v Speaker 1>Right, It's like a time constraint.

115
00:05:15.560 --> 00:05:20.519
<v Speaker 2>Yeah, exactly. The process of optimizing code can get incredibly complex. Yeah,

116
00:05:20.560 --> 00:05:22.560
<v Speaker 2>so they have to use all these different techniques and

117
00:05:22.600 --> 00:05:24.240
<v Speaker 2>they're often limited by time.

118
00:05:24.439 --> 00:05:25.839
<v Speaker 1>It's like if you were trying to solve like a

119
00:05:25.839 --> 00:05:28.040
<v Speaker 1>giant Sidoku puzzle, but you only had a certain amount

120
00:05:28.040 --> 00:05:29.720
<v Speaker 1>of time to do it. Exactly, you might not be

121
00:05:29.720 --> 00:05:32.480
<v Speaker 1>able to find the most optimal solution.

122
00:05:32.800 --> 00:05:34.000
<v Speaker 2>Yeah, exactly.

123
00:05:34.680 --> 00:05:36.639
<v Speaker 1>So how do compilers, I guess, like, how do they

124
00:05:36.839 --> 00:05:38.120
<v Speaker 1>approach this problem?

125
00:05:38.519 --> 00:05:40.920
<v Speaker 2>They use a few different techniques. One of the biggest

126
00:05:40.920 --> 00:05:44.759
<v Speaker 2>ones is data flow analysis, where they track how data

127
00:05:44.800 --> 00:05:47.160
<v Speaker 2>moves through your code. And they also use basic blocks,

128
00:05:47.519 --> 00:05:49.480
<v Speaker 2>which is where they kind of break down your code

129
00:05:49.519 --> 00:05:51.240
<v Speaker 2>into a smaller, more manageable chunk.

130
00:05:51.560 --> 00:05:54.279
<v Speaker 1>So the basic blocks are like building blocks for optimization.

131
00:05:54.920 --> 00:05:56.879
<v Speaker 2>Yeah, you could think about it that way. Yeah, it

132
00:05:56.920 --> 00:05:59.959
<v Speaker 2>makes it easier to analyze and transform the code.

133
00:06:00.120 --> 00:06:02.519
<v Speaker 1>Yeah, that's fascinating. I mean, it's incredible to see how

134
00:06:02.560 --> 00:06:05.040
<v Speaker 1>much it's happening behind the scenes, even with something that

135
00:06:05.120 --> 00:06:07.000
<v Speaker 1>seems as simple as compiling code.

136
00:06:07.040 --> 00:06:08.519
<v Speaker 2>Oh, it's a whole world down there.

137
00:06:08.639 --> 00:06:11.879
<v Speaker 1>This has been a fantastic you know, first part of

138
00:06:11.879 --> 00:06:16.639
<v Speaker 1>our journey into thinking low level writing high level. We've

139
00:06:16.720 --> 00:06:19.560
<v Speaker 1>learned a lot already about this hidden world beneath our code,

140
00:06:19.600 --> 00:06:21.720
<v Speaker 1>and there's so much more to come, and we'll pick

141
00:06:21.720 --> 00:06:24.759
<v Speaker 1>it up next time. Let's stick with us. Welcome back

142
00:06:24.800 --> 00:06:28.000
<v Speaker 1>to our deep dive. We're continuing our exploration of thinking

143
00:06:28.079 --> 00:06:29.639
<v Speaker 1>low level writing high level.

144
00:06:29.800 --> 00:06:32.759
<v Speaker 2>Yeah, we're really seeing how these low level concepts can

145
00:06:32.800 --> 00:06:34.800
<v Speaker 2>make us better high level coders.

146
00:06:34.879 --> 00:06:39.279
<v Speaker 1>Absolutely. Last time, we talked about how even simple calculations,

147
00:06:39.319 --> 00:06:41.600
<v Speaker 1>you know, they could be way more complex at that machine.

148
00:06:41.399 --> 00:06:44.680
<v Speaker 2>Level, right, and how compilers they do a lot of

149
00:06:44.680 --> 00:06:47.079
<v Speaker 2>the heavy lifting for us, but they're not always perfect.

150
00:06:47.319 --> 00:06:50.160
<v Speaker 1>Yeah, So let's dig a little deeper into some of

151
00:06:50.199 --> 00:06:54.000
<v Speaker 1>those techniques that compilers use to optimize code, and you

152
00:06:54.040 --> 00:06:56.920
<v Speaker 1>know how we can actually write code that kind of

153
00:06:56.959 --> 00:06:59.680
<v Speaker 1>plays nicely with those techniques. Yes, make sera drop easier,

154
00:07:00.040 --> 00:07:02.360
<v Speaker 1>their job easier, exactly. So one of the most fundamental

155
00:07:02.399 --> 00:07:05.560
<v Speaker 1>optimizations is constant folding. You know about constant folding.

156
00:07:05.680 --> 00:07:08.959
<v Speaker 2>Oh yeah, constant folding. It's a classic, super simple but

157
00:07:09.120 --> 00:07:10.040
<v Speaker 2>really powerful.

158
00:07:10.160 --> 00:07:12.360
<v Speaker 1>Yeah, so just remind me how does it work.

159
00:07:13.120 --> 00:07:15.600
<v Speaker 2>So let's say you have an expression in your code,

160
00:07:15.639 --> 00:07:18.800
<v Speaker 2>like you know, five plus three. A compiler that's doing

161
00:07:18.800 --> 00:07:23.279
<v Speaker 2>constant folding, it'll actually evaluate that expression at compile time

162
00:07:23.519 --> 00:07:25.560
<v Speaker 2>and just replace it with the result eight in the

163
00:07:25.600 --> 00:07:26.199
<v Speaker 2>final code.

164
00:07:26.279 --> 00:07:28.439
<v Speaker 1>So it's like pre calculating all the easy stuff so

165
00:07:28.480 --> 00:07:30.000
<v Speaker 1>the CPU doesn't have to waste time.

166
00:07:30.199 --> 00:07:32.720
<v Speaker 2>Yeah, exactly. It's low hanging fruit. Yeah, but it can

167
00:07:32.720 --> 00:07:35.160
<v Speaker 2>make a real difference, especially if you're doing that calculation

168
00:07:35.240 --> 00:07:35.600
<v Speaker 2>over and.

169
00:07:35.560 --> 00:07:38.600
<v Speaker 1>Over again, right in a loop or something exactly very cool.

170
00:07:40.040 --> 00:07:42.839
<v Speaker 1>So what other tricks do compilers have up their sleeves.

171
00:07:43.040 --> 00:07:46.879
<v Speaker 2>Well, a close relative of constant folding is constant propagation.

172
00:07:47.480 --> 00:07:47.879
<v Speaker 1>Okay.

173
00:07:47.920 --> 00:07:50.720
<v Speaker 2>This is where the compiler basically sees that you've assigned

174
00:07:50.759 --> 00:07:53.480
<v Speaker 2>a constant value to a variable, okay, and then it

175
00:07:53.639 --> 00:07:57.399
<v Speaker 2>just substitutes that value directly into expressions that use that variable. So,

176
00:07:57.560 --> 00:08:00.519
<v Speaker 2>for example, you might have pi equals three point one

177
00:08:00.639 --> 00:08:04.399
<v Speaker 2>four nine, and then later on you have circumference to

178
00:08:04.720 --> 00:08:07.560
<v Speaker 2>pie radius. Right, the compiler can just go ahead and

179
00:08:07.600 --> 00:08:09.000
<v Speaker 2>replace that pie with its.

180
00:08:08.839 --> 00:08:10.839
<v Speaker 1>Actual value throughout the code.

181
00:08:10.879 --> 00:08:13.439
<v Speaker 2>Throughout the code. Yeah, you don't even need to, you know,

182
00:08:13.920 --> 00:08:16.519
<v Speaker 2>fetch the value of pie from memory every time. It

183
00:08:16.519 --> 00:08:17.279
<v Speaker 2>saves a little.

184
00:08:17.079 --> 00:08:19.439
<v Speaker 1>Bit of time, saves a little bit of processing power. Yeah.

185
00:08:20.000 --> 00:08:23.120
<v Speaker 1>So I'm starting to see how understanding these optimizations can

186
00:08:23.160 --> 00:08:26.319
<v Speaker 1>make us more like efficient coders ourselves.

187
00:08:26.439 --> 00:08:30.319
<v Speaker 2>Absolutely, it's like you're speaking the compiler's language, helping it out.

188
00:08:30.639 --> 00:08:34.559
<v Speaker 1>So what other optimization techniques should we be aware of?

189
00:08:34.799 --> 00:08:38.240
<v Speaker 2>So another important one is dead code elimination. Okay, it's

190
00:08:38.240 --> 00:08:40.960
<v Speaker 2>pretty much what it sounds like, getting rid of dead code. Yeah,

191
00:08:41.000 --> 00:08:44.360
<v Speaker 2>any code that will never be executed like spring cleaning.

192
00:08:44.639 --> 00:08:47.320
<v Speaker 2>Yeah exactly, our program, so you might have like a

193
00:08:47.399 --> 00:08:49.399
<v Speaker 2>conditional statement, right.

194
00:08:49.399 --> 00:08:52.320
<v Speaker 1>Like an Eiffles block, one of those branches. Maybe it

195
00:08:52.320 --> 00:08:52.879
<v Speaker 1>can never be.

196
00:08:52.879 --> 00:08:54.639
<v Speaker 2>True, right, so it's never going to execute.

197
00:08:54.720 --> 00:08:56.840
<v Speaker 1>It's just never going to happen. So the compiler can

198
00:08:56.879 --> 00:08:58.559
<v Speaker 1>just go ahead and get rid of that code entirely.

199
00:08:58.720 --> 00:09:01.399
<v Speaker 2>That's great. It makes our program smaller, potentially faster.

200
00:09:01.519 --> 00:09:04.639
<v Speaker 1>What else, there's common sub expression elimination. So this is

201
00:09:04.679 --> 00:09:06.720
<v Speaker 1>where the compiler will see that you're doing the same

202
00:09:06.799 --> 00:09:10.759
<v Speaker 1>calculation multiple times with the same inputs okay, and it'll

203
00:09:10.799 --> 00:09:13.360
<v Speaker 1>just do that calculation once okay, and then use the

204
00:09:13.399 --> 00:09:14.240
<v Speaker 1>result everywhere.

205
00:09:14.559 --> 00:09:17.039
<v Speaker 2>So if I'm calculating like the area of a circle

206
00:09:17.159 --> 00:09:20.919
<v Speaker 2>over and over again with the same radius, yeah, yeah exactly,

207
00:09:20.919 --> 00:09:22.159
<v Speaker 2>it's like it can figure that out.

208
00:09:22.279 --> 00:09:24.840
<v Speaker 1>Yeah. It's basically like factoring out a common factor in

209
00:09:24.879 --> 00:09:26.799
<v Speaker 1>an equation. It simplifies things.

210
00:09:27.039 --> 00:09:30.440
<v Speaker 2>These optimizations are fascinating. I never really thought about, you know,

211
00:09:30.480 --> 00:09:34.480
<v Speaker 2>how much is going on behind the scenes, isn't it. So.

212
00:09:35.240 --> 00:09:39.039
<v Speaker 2>One more that I think it's really interesting is loop

213
00:09:39.159 --> 00:09:40.320
<v Speaker 2>invariant code motion.

214
00:09:40.639 --> 00:09:43.559
<v Speaker 1>What is that? So you have a loop, right.

215
00:09:43.639 --> 00:09:47.200
<v Speaker 2>And there's some code inside that loop that maybe it

216
00:09:47.279 --> 00:09:49.159
<v Speaker 2>doesn't actually need to be inside the loop.

217
00:09:49.240 --> 00:09:51.559
<v Speaker 1>Okay, so it's not changing every iteration.

218
00:09:51.480 --> 00:09:54.840
<v Speaker 2>Exactly, it's loop invariant. It doesn't change, right. The compiler

219
00:09:54.879 --> 00:09:57.679
<v Speaker 2>can actually take that code and move it outside the loop.

220
00:09:57.759 --> 00:09:59.519
<v Speaker 1>Okay, so it only gets executed once.

221
00:09:59.480 --> 00:10:02.360
<v Speaker 2>Yeah, exactly, and that can save you a bunch of time,

222
00:10:02.480 --> 00:10:04.919
<v Speaker 2>especially if it's a loop that's running a lot of times.

223
00:10:05.399 --> 00:10:09.440
<v Speaker 1>So these optimizations, it's like we've been driving with parking

224
00:10:09.480 --> 00:10:10.720
<v Speaker 1>brake on all this time.

225
00:10:10.879 --> 00:10:11.519
<v Speaker 2>Yeah, a little bit.

226
00:10:11.639 --> 00:10:13.440
<v Speaker 1>Yeah, and now we're learning how to take it off

227
00:10:13.720 --> 00:10:17.279
<v Speaker 1>and let our code really fly. So we've seen some

228
00:10:17.320 --> 00:10:21.159
<v Speaker 1>of these compiler techniques, but what can we do as

229
00:10:21.240 --> 00:10:26.000
<v Speaker 1>programmers to kind of write code that's more optimization friendly.

230
00:10:26.240 --> 00:10:28.159
<v Speaker 2>Well, one of the first things you got to understand

231
00:10:28.200 --> 00:10:29.519
<v Speaker 2>is operator precedence.

232
00:10:29.799 --> 00:10:31.360
<v Speaker 1>Ah, the order of operation.

233
00:10:31.519 --> 00:10:33.960
<v Speaker 2>Yeah, pem das right. We all learn that in school.

234
00:10:34.480 --> 00:10:36.759
<v Speaker 2>But it turns out compilers have to follow those same

235
00:10:36.840 --> 00:10:37.360
<v Speaker 2>rules too.

236
00:10:38.039 --> 00:10:42.320
<v Speaker 1>So if our code isn't clear about the order of operations.

237
00:10:41.879 --> 00:10:43.039
<v Speaker 2>Yeah, it can get confused.

238
00:10:43.080 --> 00:10:43.960
<v Speaker 1>It can best things up.

239
00:10:44.039 --> 00:10:45.440
<v Speaker 2>Yeah, you can get the wrong results.

240
00:10:45.600 --> 00:10:49.039
<v Speaker 1>So another important thing to consider is side effects. What

241
00:10:49.080 --> 00:10:50.000
<v Speaker 1>are side effects?

242
00:10:50.200 --> 00:10:54.200
<v Speaker 2>A side effect is basically when a statement in your

243
00:10:54.240 --> 00:10:57.600
<v Speaker 2>code does something other than just calculating a value. Ok

244
00:10:57.919 --> 00:11:00.759
<v Speaker 2>So it might change the value of a global variable

245
00:11:01.480 --> 00:11:02.679
<v Speaker 2>or write to a file.

246
00:11:02.879 --> 00:11:04.480
<v Speaker 1>Right, It's like a hidden action happening in.

247
00:11:04.480 --> 00:11:07.200
<v Speaker 2>The background, exactly. And this can make it really hard

248
00:11:07.200 --> 00:11:10.200
<v Speaker 2>for compilers to optimize code because they have to consider

249
00:11:10.240 --> 00:11:12.799
<v Speaker 2>the order in which those side effects might happen.

250
00:11:12.879 --> 00:11:15.279
<v Speaker 1>So it's like trying to I don't know, choreograph a

251
00:11:15.399 --> 00:11:17.240
<v Speaker 1>dance where some of the dancers are doing their own

252
00:11:17.240 --> 00:11:18.080
<v Speaker 1>thing off stage.

253
00:11:18.279 --> 00:11:19.559
<v Speaker 2>Yeah, that's a good analogy.

254
00:11:19.720 --> 00:11:23.240
<v Speaker 1>So minimizing side effects and making them really explicit can

255
00:11:23.279 --> 00:11:24.840
<v Speaker 1>help the compiler do its job better.

256
00:11:24.960 --> 00:11:26.759
<v Speaker 2>Yeah, make its life easier.

257
00:11:26.799 --> 00:11:29.879
<v Speaker 1>So we've got operator presidents, we've got side effects. What

258
00:11:29.919 --> 00:11:31.559
<v Speaker 1>other tips can you give us, Well, let's.

259
00:11:31.399 --> 00:11:34.279
<v Speaker 2>Talk about control structures like is statements and loops and

260
00:11:34.320 --> 00:11:35.639
<v Speaker 2>switch statements, right.

261
00:11:35.519 --> 00:11:37.279
<v Speaker 1>The things that control the flow of our code.

262
00:11:37.399 --> 00:11:40.879
<v Speaker 2>Exactly. The book talks about how to write those control

263
00:11:40.879 --> 00:11:44.279
<v Speaker 2>structures in a way that lets the compiler implement them efficiently.

264
00:11:44.799 --> 00:11:48.960
<v Speaker 2>For example, with Eiffel statements, Right, you can often figure

265
00:11:49.000 --> 00:11:51.440
<v Speaker 2>out which branch is more likely to be taken, Okay,

266
00:11:51.440 --> 00:11:54.000
<v Speaker 2>and if you structure your code so that more likely

267
00:11:54.039 --> 00:11:58.279
<v Speaker 2>branch is kind of the default path that can help

268
00:11:58.360 --> 00:12:01.559
<v Speaker 2>the compiler generate more effect It's like planning.

269
00:12:01.320 --> 00:12:02.919
<v Speaker 1>A route where you're probably going to take the highway

270
00:12:02.960 --> 00:12:05.559
<v Speaker 1>instead the back roads. Yeah, exactly, you know, make it,

271
00:12:05.600 --> 00:12:07.000
<v Speaker 1>make it the most efficient path.

272
00:12:07.279 --> 00:12:10.440
<v Speaker 2>The book also talks about switch statements, which can be

273
00:12:10.480 --> 00:12:13.720
<v Speaker 2>optimized using things like jump tables, which are really interesting.

274
00:12:13.799 --> 00:12:15.240
<v Speaker 1>Some tables. What's a jump table?

275
00:12:15.840 --> 00:12:19.799
<v Speaker 2>So imagine like a table that maps each possible case

276
00:12:19.879 --> 00:12:23.879
<v Speaker 2>value in the switch statement to the corresponding block of code. Okay,

277
00:12:24.080 --> 00:12:26.919
<v Speaker 2>so instead of like evaluating a bunch of conditions, it

278
00:12:26.960 --> 00:12:29.080
<v Speaker 2>can just jumped right to the right place.

279
00:12:29.360 --> 00:12:33.000
<v Speaker 1>So it's like a super efficient lookup table for code execution.

280
00:12:33.200 --> 00:12:33.799
<v Speaker 2>Yeah, you got it.

281
00:12:33.919 --> 00:12:38.240
<v Speaker 1>Okay. What about loops? Loops? You know they're so essential,

282
00:12:38.440 --> 00:12:41.120
<v Speaker 1>but they can also be a big performance bottleneck. Oh yeah,

283
00:12:41.159 --> 00:12:42.960
<v Speaker 1>for sure if we're not careful. Yeah.

284
00:12:43.279 --> 00:12:46.159
<v Speaker 2>The book talks about how to avoid writing code that's

285
00:12:46.200 --> 00:12:48.639
<v Speaker 2>going to get in the compiler's way when it's trying

286
00:12:48.639 --> 00:12:52.919
<v Speaker 2>to optimize loops. So things like minimizing the amount of

287
00:12:52.919 --> 00:12:55.639
<v Speaker 2>work you're doing inside the loop right and using loop

288
00:12:55.679 --> 00:12:59.320
<v Speaker 2>counters effectively. It's about making that loop really predictable.

289
00:12:59.480 --> 00:13:02.879
<v Speaker 1>This is like streamlining the assembly line exact to make

290
00:13:02.919 --> 00:13:04.279
<v Speaker 1>it as smooth as possible.

291
00:13:04.360 --> 00:13:04.840
<v Speaker 2>You got it.

292
00:13:04.960 --> 00:13:07.879
<v Speaker 1>Wow, this is incredible. It's amazing to see all these

293
00:13:07.879 --> 00:13:10.879
<v Speaker 1>optimizations that are happening that most of us probably don't

294
00:13:10.919 --> 00:13:11.559
<v Speaker 1>even think about.

295
00:13:11.759 --> 00:13:13.360
<v Speaker 2>Yeah, it's a whole world down there.

296
00:13:14.000 --> 00:13:16.200
<v Speaker 1>So this has been a really insightful look into the

297
00:13:16.200 --> 00:13:17.919
<v Speaker 1>world of compiler optimization.

298
00:13:17.960 --> 00:13:19.399
<v Speaker 2>It's amazing what they can do, isn't it.

299
00:13:19.600 --> 00:13:22.480
<v Speaker 1>And how you know, we as programmers can actually help

300
00:13:22.519 --> 00:13:22.840
<v Speaker 1>them out a.

301
00:13:22.840 --> 00:13:24.639
<v Speaker 2>Little bit, give them a hand exactly.

302
00:13:25.120 --> 00:13:27.559
<v Speaker 1>But we're not done yet. There's still more to explore

303
00:13:27.600 --> 00:13:31.200
<v Speaker 1>in thinking low level writing high level. Stick with us

304
00:13:31.240 --> 00:13:36.639
<v Speaker 1>for the final part of our deep dive. Welcome back.

305
00:13:36.919 --> 00:13:39.960
<v Speaker 1>It's the final part of our deep dive into thinking

306
00:13:40.039 --> 00:13:41.879
<v Speaker 1>low level writing high level.

307
00:13:42.120 --> 00:13:43.679
<v Speaker 2>We've covered a lot of ground, haven't we.

308
00:13:43.840 --> 00:13:46.840
<v Speaker 1>Yeah, it's been a real journey exploring how those low

309
00:13:46.960 --> 00:13:49.960
<v Speaker 1>level assembly concepts, you know, they can inform the way

310
00:13:50.000 --> 00:13:51.279
<v Speaker 1>we write high level code.

311
00:13:51.519 --> 00:13:53.519
<v Speaker 2>Yeah, it's all about building that intuition.

312
00:13:53.960 --> 00:13:57.440
<v Speaker 1>Yeah, Like understanding those fundamental principles, even if we're not

313
00:13:57.440 --> 00:13:58.720
<v Speaker 1>writing assembly code every.

314
00:13:58.679 --> 00:14:01.360
<v Speaker 2>Day, right, makes you a better programmer overall, no matter

315
00:14:01.360 --> 00:14:02.360
<v Speaker 2>what language you're using.

316
00:14:02.519 --> 00:14:04.879
<v Speaker 1>Absolutely, So for this last part, I want to focus

317
00:14:04.960 --> 00:14:07.879
<v Speaker 1>on a specific data structure, one that we use all

318
00:14:07.919 --> 00:14:09.279
<v Speaker 1>the time. Strings.

319
00:14:09.440 --> 00:14:13.279
<v Speaker 2>Strings. Ah, yes, those simple sequences of characters.

320
00:14:13.480 --> 00:14:16.519
<v Speaker 1>Yeah, but as we'll see, you know, there's more to

321
00:14:16.559 --> 00:14:17.639
<v Speaker 1>them than meets the eye.

322
00:14:17.879 --> 00:14:20.519
<v Speaker 2>There's a lot going on under the hood. Different ways

323
00:14:20.519 --> 00:14:22.120
<v Speaker 2>to represent them in memory.

324
00:14:21.799 --> 00:14:23.960
<v Speaker 1>Right, and they can have a big impact on performance

325
00:14:24.000 --> 00:14:24.919
<v Speaker 1>and memory usage.

326
00:14:24.960 --> 00:14:28.399
<v Speaker 2>Absolutely. So let's talk about some of those different ways

327
00:14:28.440 --> 00:14:29.440
<v Speaker 2>to represent strings.

328
00:14:29.639 --> 00:14:32.480
<v Speaker 1>Yeah, refresh my memory. What are some of the common types.

329
00:14:32.919 --> 00:14:35.279
<v Speaker 2>Well, the one you probably see most often is the

330
00:14:35.399 --> 00:14:36.600
<v Speaker 2>zero terminated string.

331
00:14:36.720 --> 00:14:38.080
<v Speaker 1>Oh yeah, the null terminator.

332
00:14:38.159 --> 00:14:41.519
<v Speaker 2>Yeah. Classic. Yeah. It's basically just an array of characters, right,

333
00:14:41.799 --> 00:14:43.840
<v Speaker 2>but at the very end there's a special character, a

334
00:14:43.919 --> 00:14:46.960
<v Speaker 2>null character represented as zero and no. Yeah, that's it,

335
00:14:47.159 --> 00:14:48.759
<v Speaker 2>and that signals the end of the string.

336
00:14:49.000 --> 00:14:50.960
<v Speaker 1>Simple effect it is, But.

337
00:14:50.960 --> 00:14:54.600
<v Speaker 2>It has one little quirk. Since that null character marks

338
00:14:54.600 --> 00:14:57.279
<v Speaker 2>the end, you can't have any null characters within the

339
00:14:57.320 --> 00:14:58.080
<v Speaker 2>string itself.

340
00:14:58.240 --> 00:15:01.159
<v Speaker 1>Oh, I see. That could be a problem if you're

341
00:15:01.159 --> 00:15:03.519
<v Speaker 1>trying to store certain types.

342
00:15:03.279 --> 00:15:06.559
<v Speaker 2>Of data, yeah, like binary data or texts that might

343
00:15:06.600 --> 00:15:09.000
<v Speaker 2>contain nulls. For that, you might need a different type

344
00:15:09.039 --> 00:15:09.399
<v Speaker 2>of string.

345
00:15:09.519 --> 00:15:11.000
<v Speaker 1>Okay, so what's another option.

346
00:15:11.200 --> 00:15:13.480
<v Speaker 2>Another one is the length prefixed.

347
00:15:13.000 --> 00:15:14.919
<v Speaker 1>String length prefix Okay.

348
00:15:14.919 --> 00:15:18.320
<v Speaker 2>Instead of relying on a terminator, it stores the length

349
00:15:18.360 --> 00:15:21.360
<v Speaker 2>of the string explicitly, usually as an integer right at

350
00:15:21.399 --> 00:15:21.840
<v Speaker 2>the beginning.

351
00:15:21.919 --> 00:15:23.919
<v Speaker 1>So it's like the string is carrying a little size.

352
00:15:23.639 --> 00:15:26.559
<v Speaker 2>Tag exactly tells you exactly how many characters there are,

353
00:15:26.639 --> 00:15:26.960
<v Speaker 2>so you.

354
00:15:26.879 --> 00:15:28.960
<v Speaker 1>Can have any character you want within the string itself.

355
00:15:29.039 --> 00:15:32.679
<v Speaker 2>Yeah, null characters, no problem. The downside is you need

356
00:15:32.679 --> 00:15:35.320
<v Speaker 2>a little extra space to store that length information.

357
00:15:35.679 --> 00:15:38.440
<v Speaker 1>Uh. Trade offs, y, always, trade offs always.

358
00:15:38.879 --> 00:15:42.440
<v Speaker 2>The book also talks about HLA strings, which are specific

359
00:15:42.519 --> 00:15:44.080
<v Speaker 2>to the HLA language.

360
00:15:43.759 --> 00:15:45.960
<v Speaker 1>High Level Assembly HLA strings.

361
00:15:45.600 --> 00:15:48.200
<v Speaker 2>And they kind of combine elements of zero terminated and

362
00:15:48.320 --> 00:15:51.000
<v Speaker 2>length prefix a hybrid approach. Yeah, you could say that.

363
00:15:51.159 --> 00:15:54.759
<v Speaker 1>Interesting. Now there's another type of string that I've always

364
00:15:54.759 --> 00:15:59.559
<v Speaker 1>been a little fuzzy on. Descripture based strings. Ah.

365
00:15:59.639 --> 00:16:02.039
<v Speaker 2>Yes, descriptor based strings.

366
00:16:02.399 --> 00:16:02.919
<v Speaker 1>What are those?

367
00:16:03.000 --> 00:16:06.399
<v Speaker 2>So instead of storing the string data directly, they use

368
00:16:06.399 --> 00:16:09.399
<v Speaker 2>a separate data structure called a descriptor. Okay, and that

369
00:16:09.480 --> 00:16:13.320
<v Speaker 2>descriptor it points to the actual string data, right, but

370
00:16:13.440 --> 00:16:15.360
<v Speaker 2>it also contains information about the string.

371
00:16:15.720 --> 00:16:17.840
<v Speaker 1>So it's like a filefolder that tells you about the strength.

372
00:16:17.960 --> 00:16:20.080
<v Speaker 2>Yeah, good analogy. It gives you the length the character

373
00:16:20.120 --> 00:16:23.440
<v Speaker 2>said all that stuff. The advantage is flexibility, right, you

374
00:16:23.480 --> 00:16:26.200
<v Speaker 2>can share string data more easily. Okay, but there's an

375
00:16:26.200 --> 00:16:28.399
<v Speaker 2>extra layer of indirection there, so it can be a

376
00:16:28.399 --> 00:16:29.159
<v Speaker 2>bit slower.

377
00:16:29.399 --> 00:16:31.879
<v Speaker 1>I see. So each type of string has its pros

378
00:16:31.919 --> 00:16:32.440
<v Speaker 1>and cons.

379
00:16:32.600 --> 00:16:34.120
<v Speaker 2>Yeah, depends on what you're trying to do.

380
00:16:34.399 --> 00:16:37.919
<v Speaker 1>Now, beyond these basic types, the book mentions some more

381
00:16:37.960 --> 00:16:42.480
<v Speaker 1>specialized string representations, like reference counted strings.

382
00:16:42.679 --> 00:16:45.039
<v Speaker 2>Ah. Yes, reference counting, that's a clever one.

383
00:16:45.120 --> 00:16:46.679
<v Speaker 1>That's a memory management technique, right.

384
00:16:46.759 --> 00:16:50.240
<v Speaker 2>It is, each string keeps track of how many references

385
00:16:50.279 --> 00:16:53.480
<v Speaker 2>to it exist, like how many pointers are pointing to it.

386
00:16:53.840 --> 00:16:56.799
<v Speaker 2>When that count goes to zero, nobody's using it. The

387
00:16:56.840 --> 00:16:57.679
<v Speaker 2>memory gets.

388
00:16:57.440 --> 00:17:00.120
<v Speaker 1>Freed, so it's like a self cleaning system exactly.

389
00:17:00.240 --> 00:17:01.720
<v Speaker 2>Helps prevent memory leaks.

390
00:17:01.759 --> 00:17:05.440
<v Speaker 1>Okay, and then there's the whole world of Unicode strings Unicode,

391
00:17:07.160 --> 00:17:09.039
<v Speaker 1>but it also introduces some challenges, right.

392
00:17:09.119 --> 00:17:13.200
<v Speaker 2>Yeah, Unicode can represent characters from any writing system, which

393
00:17:13.240 --> 00:17:17.920
<v Speaker 2>is amazing, right, But those characters, they might take up

394
00:17:18.039 --> 00:17:21.440
<v Speaker 2>more space than a simple ASKI character, right.

395
00:17:21.359 --> 00:17:24.279
<v Speaker 1>Because Unicode has to handle a much larger set of characters.

396
00:17:24.400 --> 00:17:27.880
<v Speaker 2>Yeah, exactly, So string operations might take a little longer.

397
00:17:28.200 --> 00:17:29.359
<v Speaker 1>So it's something to keep in mind.

398
00:17:29.519 --> 00:17:31.920
<v Speaker 2>Definitely, especially if performance is critical.

399
00:17:32.240 --> 00:17:35.200
<v Speaker 1>This has been a really eye opening look into strings.

400
00:17:35.599 --> 00:17:37.799
<v Speaker 1>You know, I use them every day, but I never

401
00:17:37.839 --> 00:17:40.400
<v Speaker 1>really thought about the different ways they can be represented.

402
00:17:40.799 --> 00:17:43.400
<v Speaker 2>It's a good reminder that even those basic building blocks

403
00:17:43.440 --> 00:17:44.559
<v Speaker 2>have their own complexities.

404
00:17:44.759 --> 00:17:47.559
<v Speaker 1>Absolutely. Now, before we wrap up, I want to touch

405
00:17:47.599 --> 00:17:49.640
<v Speaker 1>on something else. The book talks about something that really

406
00:17:49.680 --> 00:17:52.920
<v Speaker 1>surprised me. What's that The impact of file organization on

407
00:17:53.039 --> 00:17:54.079
<v Speaker 1>code efficiency.

408
00:17:54.480 --> 00:17:58.160
<v Speaker 2>File organization, it might not seem obvious, but it can

409
00:17:58.200 --> 00:17:58.880
<v Speaker 2>make a difference.

410
00:17:58.960 --> 00:18:01.720
<v Speaker 1>Yeah, I never thought about it. So how does that work?

411
00:18:02.279 --> 00:18:06.359
<v Speaker 2>So operating systems they manage memory in chunks, right, okay,

412
00:18:06.599 --> 00:18:08.599
<v Speaker 2>And if you organize your code, well, you can make

413
00:18:08.640 --> 00:18:11.440
<v Speaker 2>it easier for the operating system to load and manage

414
00:18:11.480 --> 00:18:12.039
<v Speaker 2>those chunks.

415
00:18:12.079 --> 00:18:14.240
<v Speaker 1>I see. So it's like if you're packing a suitcase,

416
00:18:14.279 --> 00:18:15.839
<v Speaker 1>you want to put all the heavy stuff together.

417
00:18:16.000 --> 00:18:17.359
<v Speaker 2>Yeah, kind of like that, so.

418
00:18:17.359 --> 00:18:19.920
<v Speaker 1>You're not constantly digging around for things exactly.

419
00:18:20.119 --> 00:18:22.640
<v Speaker 2>The book talks about things like locality of reference.

420
00:18:22.720 --> 00:18:24.480
<v Speaker 1>Locality of reference Okay.

421
00:18:24.240 --> 00:18:28.759
<v Speaker 2>It means if your program accesses one memory location, it's

422
00:18:28.799 --> 00:18:31.880
<v Speaker 2>probably going to access nearby locations soon after.

423
00:18:32.240 --> 00:18:34.160
<v Speaker 1>So keep related things together, keep.

424
00:18:33.960 --> 00:18:36.319
<v Speaker 2>Things close, makes everything run smoother.

425
00:18:36.799 --> 00:18:40.039
<v Speaker 1>Fascinating. Well, I think we've just about reached the end

426
00:18:40.039 --> 00:18:42.400
<v Speaker 1>of our deep dive. It's been quite a journey, it

427
00:18:42.440 --> 00:18:45.720
<v Speaker 1>really has. We've explored so much about how those low

428
00:18:45.799 --> 00:18:50.119
<v Speaker 1>level concepts they can inform and empower our high level.

429
00:18:49.880 --> 00:18:53.759
<v Speaker 2>Coding, even if we never read a line of assembly ourselves.

430
00:18:53.519 --> 00:18:57.680
<v Speaker 1>Exactly, And you know, it's not about becoming assembly language experts.

431
00:18:57.920 --> 00:19:02.000
<v Speaker 1>It's about developing that low level intouition, that ability to

432
00:19:02.079 --> 00:19:04.000
<v Speaker 1>see how things really work under the.

433
00:19:03.920 --> 00:19:06.720
<v Speaker 2>Hood and write better code as a result, exactly.

434
00:19:07.039 --> 00:19:10.519
<v Speaker 1>So keep exploring, keep learning, and keep pushing the boundaries

435
00:19:10.640 --> 00:19:11.839
<v Speaker 1>of what's possible with code.

436
00:19:11.960 --> 00:19:13.920
<v Speaker 2>Happy coding everyone, until next time.
