├── README.md ├── contribution.md ├── integrals.md ├── scripts ├── format-chinese-subtitle.lua └── google_trans.py └── subtitle ├── Chinese_English ├── Lecture 01 course_overview.ass ├── Lecture 02 Bits, Bytes, and Integers.ass ├── Lecture 03 Bits, Bytes, and Integers cont.ass ├── Lecture 04 Floating Point.ass ├── Lecture 05 Machine Level Programming I Basics.ass ├── Lecture 06 Machine Level Programming II Control.ass ├── Lecture 07 Machine Level Programming III Procedures.ass ├── Lecture 08 Machine Level Programming IV Data.ass ├── Lecture 09 Machine Level Programming V Advanced Topics.ass ├── Lecture 10 Program Optimization.ass ├── Lecture 11 The Memory Hierarchy.ass ├── Lecture 12 Cache Memories.ass ├── Lecture 13 Linking.ass ├── Lecture 14 Exceptional Control Flow Exceptions and Processes.ass ├── Lecture 15 Exceptional Control Flow Signals and Nonlocal Jumps.ass ├── Lecture 16 System Level I_O.ass ├── Lecture 17 Virtual Memory Concepts.ass ├── Lecture 18 Virtual Memory Systems.ass ├── Lecture 19 Dynamic Memory Allocation Basic Concepts.ass ├── Lecture 20 Dynamic Memory Allocation Advanced Concepts.ass ├── Lecture 21 Network Programming Part 1.ass ├── Lecture 22 Network Programming Part II.ass ├── Lecture 23 Concurrent Programming.ass ├── Lecture 24 Synchronization Basics.ass ├── Lecture 25 Synchronization Advanced.ass └── Lecture 26 Thread Level Parallelism.ass ├── English ├── Lecture 01 course_overview.ass ├── Lecture 02 Bits, Bytes, and Integers.ass ├── Lecture 03 Bits, Bytes, and Integers cont.ass ├── Lecture 04 Floating Point.ass ├── Lecture 05 Machine Level Programming I Basics.ass ├── Lecture 06 Machine Level Programming II Control.ass ├── Lecture 07 Machine Level Programming III Procedures.ass ├── Lecture 08 Machine Level Programming IV Data.ass ├── Lecture 09 Machine Level Programming V Advanced Topics.ass ├── Lecture 10 Program Optimization.ass ├── Lecture 11 The Memory Hierarchy.ass ├── Lecture 12 Cache Memories.ass ├── Lecture 13 Linking.ass ├── Lecture 14 Exceptional Control Flow Exceptions and Processes.ass ├── Lecture 15 Exceptional Control Flow Signals and Nonlocal Jumps.ass ├── Lecture 16 System Level I_O.ass ├── Lecture 17 Virtual Memory Concepts.ass ├── Lecture 18 Virtual Memory Systems.ass ├── Lecture 19 Dynamic Memory Allocation Basic Concepts.ass ├── Lecture 20 Dynamic Memory Allocation Advanced Concepts.ass ├── Lecture 21 Network Programming Part 1.ass ├── Lecture 22 Network Programming Part II.ass ├── Lecture 23 Concurrent Programming.ass ├── Lecture 24 Synchronization Basics.ass ├── Lecture 25 Synchronization Advanced.ass ├── Lecture 26 Thread Level Parallelism.ass └── Lecture 27 Future of Computing.ass ├── auto_generated ├── English (auto-generated)Lecture 13 Linking.srt ├── English (auto-generated)Lecture 14 Exceptional Control Flow Exceptions and Processes.srt ├── English (auto-generated)Lecture 15 Exceptional Control Flow Signals and Nonlocal Jumps.ass ├── English (auto-generated)Lecture 15 Exceptional Control Flow Signals and Nonlocal Jumps.srt ├── English (auto-generated)Lecture 16 System Level I_O.srt ├── English (auto-generated)Lecture 17 Virtual Memory Concepts.srt ├── English (auto-generated)Lecture 18 Virtual Memory Systems.srt ├── English (auto-generated)Lecture 19 Dynamic Memory Allocation Basic Concepts.ass ├── English (auto-generated)Lecture 19 Dynamic Memory Allocation Basic Concepts.srt ├── English (auto-generated)Lecture 20 Dynamic Memory Allocation Advanced Concepts.srt ├── English (auto-generated)Lecture 21 Network Programming Part 1.srt ├── English (auto-generated)Lecture 22 Network Programming Part II.srt ├── English (auto-generated)Lecture 23 Concurrent Programming.srt ├── English (auto-generated)Lecture 24 Synchronization Basics.srt ├── English (auto-generated)Lecture 25 Synchronization Advanced.srt ├── English (auto-generated)Lecture 26 Thread Level Parallelism.srt ├── English (auto-generated)Lecture 27 Future of Computing.ass ├── English (auto-generated)Lecture 27 Future of Computing.srt ├── English (auto-generated)Recitation 1102 Virtual Memory.srt ├── Lecture 13 Linking.ass └── Lecture 15 Exceptional Control Flow Signals and Nonlocal Jumps.ass └── translation ├── Lecture 01 course_overview.ass ├── Lecture 02 Bits, Bytes, and Integers.ass ├── Lecture 03 Bits, Bytes, and Integers cont.ass ├── Lecture 04 Floating Point.ass ├── Lecture 05 Machine Level Programming I Basics.ass ├── Lecture 06 Machine Level Programming II Control.ass ├── Lecture 07 Machine Level Programming III Procedures.ass ├── Lecture 08 Machine Level Programming IV Data.ass ├── Lecture 09 Machine Level Programming V Advanced Topics.ass ├── Lecture 10 Program Optimization.ass ├── Lecture 11 The Memory Hierarchy.ass ├── Lecture 12 Cache Memories.ass ├── Lecture 13 Linking.ass ├── Lecture 14 Exceptional Control Flow Exceptions and Processes.ass ├── Lecture 15 Exceptional Control Flow Signals and Nonlocal Jumps.ass ├── Lecture 16 System Level I_O.ass ├── Lecture 17 Virtual Memory Concepts.ass ├── Lecture 18 Virtual Memory Systems.ass ├── Lecture 19 Dynamic Memory Allocation Basic Concepts.ass ├── Lecture 20 Dynamic Memory Allocation Advanced Concepts.ass ├── Lecture 21 Network Programming Part 1.ass ├── Lecture 22 Network Programming Part II.ass ├── Lecture 23 Concurrent Programming.ass ├── Lecture 24 Synchronization Basics.ass ├── Lecture 25 Synchronization Advanced.ass ├── Lecture 26 Thread Level Parallelism.ass └── Lecture 27 Future of Computing.ass /README.md: -------------------------------------------------------------------------------- 1 | # 中英双语字幕精校版 CSAPP CMU 15-213 课程 2015 Fall 视频翻译计划 2 | 3 | > 本项目的英文字幕以 Youtube 视频机器字幕为底稿,经过审校和和时间轴调整而来。每个视频的字幕均经过一位译者翻译,1-2 位校对者校对,一位管理员审校。 4 | 5 | **如果你也对这个项目感兴趣,请阅读 [WIKI 中的指南](https://github.com/EugeneLiu/translationCSAPP/wiki),按照指引参与项目的贡献,感谢大家的支持。** 6 | 7 | ## 翻译内容链接 8 | 9 | - [bilibili 中英字幕精校版视频地址(进行中)](https://www.bilibili.com/video/av31289365) 10 | 11 | ## CSAPP:3e 官方链接 12 | 13 | - [课程主页](http://csapp.cs.cmu.edu/) 14 | - [课件下载链接](http://www.cs.cmu.edu/afs/cs/academic/class/15213-f15/www/schedule.html) 15 | - [课程 Lab 页面](http://csapp.cs.cmu.edu/3e/labs.html) 16 | - [课程视频地址](https://scs.hosted.panopto.com/Panopto/Pages/Sessions/List.aspx#folderID=%22b96d90ae-9871-4fae-91e2-b1627b43e25e%22&sortColumn=0&sortAscending=true) 17 | 18 | ## 其他链接 19 | 20 | - [bilibili 纯英文字幕全集视频地址](https://www.bilibili.com/video/av24540152) 21 | - [Youtube 视频源地址](https://www.youtube.com/playlist?list=PLmBgoRqEQCWy58EIwLSWwMPfkwLOLRM5R) 22 | - [Google 翻译版中英字幕 未校对](https://github.com/huqianshan/translationCSAPP/tree/master/subtitle/Chinese_English) 23 | 24 | ## 版权相关 25 | 26 | ![creative commons logo](https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png) 本作品采用[知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议](http://creativecommons.org/licenses/by-nc-sa/4.0/)进行许可。 27 | -------------------------------------------------------------------------------- /contribution.md: -------------------------------------------------------------------------------- 1 | ## 参与制作 CSAPP 课程字幕 2 | 3 | ### 制作流程 4 | 5 | > 使用 YouTube 自动生成的机器字幕为底稿调整时间轴,然后通过脚本将英文字幕翻译成中文进行校对 6 | 7 | 调整时间轴 —> 校对英文字幕 —> 翻译中文字幕 —> 精校 —> 压制 —> 发布 8 | 9 | > 翻译中文字幕具体流程 10 | 11 | 参与翻译的同学会分配到一定的翻译任务,一般会是1个课时,或者某个课时的200-500轴的任务。接受任务的同学最好能在1周之内通过 pull request 的方式提交自己的成果。翻译中间有任何问题可以通过 issues 方式来沟通或者直接在群里沟通。 12 | 13 | ### 制作规范 14 | 15 | * 时间轴尽量精确,每个句子的轴从第一个单词的发音开始 16 | * 英文字幕,每个句子的首字母必须大写,结尾不需要句号 17 | * 尽量删除重复的单词 18 | * 中文字幕,使用[中文文案排版指北](https://github.com/mzlogin/chinese-copywriting-guidelines/blob/Simplified/README.md)规范 19 | * 寄存器,字幕中提到的寄存器必须在寄存器名字前面加上百分号(%),寄存器的名字必须小写。比如:%rbx 20 | * 幂指数,使用表达式 2^m 的形式表示2的m次幂 21 | * 计算式子,字幕中直接使用数学式子代替英文单词,比如 1+2+4=7 代替 one plus two plus four equal seven 22 | 23 | #### 制作软件 24 | 25 | * 使用[ aegisub ](http://www.aegisub.org/)制作字幕 26 | * 使用[小丸工具箱](https://maruko.appinn.me/)压制 27 | 28 | #### 字幕字体 29 | 30 | * 使用[ Noto Sans CJK SC ](https://noto-website-2.storage.googleapis.com/pkgs/NotoSansCJKsc-hinted.zip)作为中英文字体,Black字重。(Noto Sans CJK SC 就是 思源黑体) 31 | * 字体颜色待定 32 | 33 | #### 协同工作 34 | 35 | * 使用 Github 作为字幕文件管理仓库 36 | * 使用[ forking 工作流](https://github.com/xirong/my-git/blob/master/git-workflow-tutorial.md#24-forking%E5%B7%A5%E4%BD%9C%E6%B5%81) 37 | * 参与者需要 fork 该[项目](https://github.com/EugeneLiu/translationCSAPP),并告知准备参与的制作的内容。修改完成之后,需要发起 pull request 将代码合并到主项目 38 | 39 | ### 联系方式 40 | 41 | * 个人邮箱:eugene.liujing.zh@gmail.com 42 | * QQ 交流群:818970413 43 | 44 | #### 具体分工 45 | 46 | > 1课时初步制作的[ B站链接](https://www.bilibili.com/video/av24540152),[中英字幕精校B站链接](https://www.bilibili.com/video/av31289365) 47 | 48 | | | 时间轴 | 英文校对 | 中文校对 | 精校 | 压制 | 发布 | 49 | | ------ | :----: | :------: | :------------------------------------------------------: | :----------------------------------------------: | :----: | :----: | 50 | | 1课时 | 已完成 | 已完成 | 已完成( [@eggycat](https://github.com/EggyCat)) | 已完成([@eggycat](https://github.com/EggyCat)) | 已完成 | 已完成 | 51 | | 2课时 | 已完成 | 已完成 | 已完成(严FL) | 进行中([@eggycat](https://github.com/EggyCat)) | 已完成 | 已完成 | 52 | | 3课时 | 已完成 | 已完成 | 已完成([@nukeexplode](https://github.com/nukeexplode)) | | | | 53 | | 4课时 | 已完成 | 已完成 | 进行中(Milton) | | | | 54 | | 5课时 | 已完成 | 已完成 | 进行中( [@eggycat](https://github.com/EggyCat)) | | | | 55 | | 6课时 | 已完成 | 已完成 | 进行中(🌚) | | | | 56 | | 7课时 | 已完成 | 已完成 | 已完成([@ivylijingru](https://github.com/ivylijingru)) | | | | 57 | | 8课时 | 已完成 | 已完成 | 进行中(Coiby) | | | | 58 | | 9课时 | 已完成 | 已完成 | | | | | 59 | | 10课时 | 已完成 | 已完成 | | | | | 60 | | 11课时 | 已完成 | 已完成 | | | | | 61 | | 12课时 | 已完成 | 已完成 | | | | | 62 | | 13课时 | 已完成 | 已完成 | | | | | 63 | | 14课时 | 已完成 | 已完成 | | | | | 64 | | 15课时 | 已完成 | 已完成 | | | | | 65 | | 16课时 | 已完成 | 已完成 | | | | | 66 | | 17课时 | 已完成 | 已完成 | | | | | 67 | | 18课时 | 已完成 | 已完成 | | | | | 68 | | 19课时 | 已完成 | 已完成 | | | | | 69 | | 20课时 | 已完成 | 已完成 | | | | | 70 | | 21课时 | 已完成 | 已完成 | | | | | 71 | | 22课时 | 已完成 | 已完成 | | | | | 72 | | 23课时 | 已完成 | 已完成 | | | | | 73 | | 24课时 | 已完成 | 已完成 | | | | | 74 | | 25课时 | 已完成 | 已完成 | | | | | 75 | | 26课时 | 已完成 | 已完成 | | | | | 76 | | 27课时 | | | | | | | 77 | 78 | -------------------------------------------------------------------------------- /integrals.md: -------------------------------------------------------------------------------- 1 | # 译者积分表 2 | 3 | > 注:该文档由管理员修改,如有疑问请联系管理员。 4 | 5 | ## 译者:[eggycat](https://github.com/EggyCat)历史贡献积分:7,当前积分:7 6 | 7 | | 课程 | 类型 | 积分 | 8 | | ------------------------------------------------------------ | ---------- | ---- | 9 | | [ Lecture 01 course_overview.ass](https://github.com/EugeneLiu/translationCSAPP/blob/master/subtitle/translation/Lecture%2001%20%20course_overview.ass) | 翻译、校对 | 7 | 10 | 11 | ## 译者:*yanfl* 历史贡献积分:5,当前积分:5 12 | 13 | | 课程 | 类型 | 积分 | 14 | | ------------------------------------------------------------ | ---- | ---- | 15 | | [Lecture 02 Bits, Bytes, and Integers.ass](https://github.com/EugeneLiu/translationCSAPP/blob/master/subtitle/translation/Lecture%2002%20%20Bits%2C%20Bytes%2C%20and%20Integers.ass) | 翻译 | 5 | 16 | 17 | ## 译者:[Jinzhengxu](https://github.com/Jinzhengxu) 历史贡献积分:2,当前积分:2 18 | 19 | | 课程 | 类型 | 积分 | 20 | | ------------------------------------------------------------ | ---- | ---- | 21 | | [Lecture 02 Bits, Bytes, and Integers.ass](https://github.com/EugeneLiu/translationCSAPP/blob/master/subtitle/translation/Lecture%2002%20%20Bits%2C%20Bytes%2C%20and%20Integers.ass) | 校对 | 2 | 22 | 23 | ## 译者:[nukeexplode](https://github.com/nukeexplode)历史贡献积分:5,当前积分:5 24 | 25 | | 课程 | 类型 | 积分 | 26 | | ------------------------------------------------------------ | ---- | ---- | 27 | | [Lecture 03 Bits, Bytes, and Integers cont.ass](https://github.com/EugeneLiu/translationCSAPP/blob/master/subtitle/translation/Lecture%2003%20%20Bits%2C%20Bytes%2C%20and%20Integers%20cont.ass) | 翻译 | 5 | 28 | 29 | ## 译者:[sunlianqiang](https://github.com/sunlianqiang)历史贡献积分:5,当前积分:5 30 | 31 | | 课程 | 类型 | 积分 | 32 | | ------------------------------------------------------------ | ---- | ---- | 33 | | [Lecture 04 Floating Point.ass](https://github.com/EugeneLiu/translationCSAPP/blob/master/subtitle/translation/Lecture%2004%20%20Floating%20Point.ass) | 翻译 | 5 | 34 | 35 | ## 译者:[ivylijingru](https://github.com/ivylijingru)历史贡献积分:5,当前积分:5 36 | 37 | | 课程 | 类型 | 积分 | 38 | | ------------------------------------------------------------ | ---- | ---- | 39 | | [Lecture 07 Machine Level Programming III Procedures.ass](https://github.com/EugeneLiu/translationCSAPP/blob/master/subtitle/translation/Lecture%2007%20%20Machine%20Level%20Programming%20III%20%20Procedures.ass) | 翻译 | 5 | 40 | 41 | -------------------------------------------------------------------------------- /scripts/format-chinese-subtitle.lua: -------------------------------------------------------------------------------- 1 | -- Automation 4 demo script 2 | -- use blank split Chinese character and English character or number character 3 | 4 | script_name = "格式化中文字幕" 5 | script_description = "依照中文排版指北将中文字符和英文字符或者数字使用空格隔开" 6 | script_author = "Eugene Liu" 7 | script_version = "1.0.0" 8 | 9 | re = require 'aegisub.re' 10 | 11 | function format_chinese_line(line) 12 | if line.style == 'Chinese' then 13 | local out_str, rep_count 14 | out_str, rep_count = re.sub(line.text, "([\\u2000-\\u206F\\u3000-\\u303F\\u4E00-\\u9FBF\\uFF00-\\uFFEF^\\.^\\s]+)", " \\1 ") 15 | line.text = out_str 16 | return line 17 | else 18 | return line 19 | end 20 | end 21 | 22 | function format_chinese_subtitle(subtitles, selected_lines, active_line) 23 | config = { 24 | {class="label", label="请使用 Chinese 作为中文字幕的样式名", x=0, y=0} 25 | } 26 | btn, result = aegisub.dialog.display(config, 27 | {"当前选中中文字幕", "全部中文字幕"}, 28 | {select="当前选中中文字幕", all="全部中文字幕"}) 29 | 30 | if btn == "当前选中中文字幕" then 31 | for z, i in ipairs(selected_lines) do 32 | local line = subtitles[i] 33 | subtitles[i] = format_chinese_line(line) 34 | end 35 | elseif btn == "全部中文字幕" then 36 | for i=1, #subtitles do 37 | local line = subtitles[i] 38 | subtitles[i] = format_chinese_line(subtitles[i]) 39 | end 40 | else 41 | end 42 | aegisub.set_undo_point(script_name) 43 | end 44 | 45 | aegisub.register_macro(script_name, script_description, format_chinese_subtitle) -------------------------------------------------------------------------------- /scripts/google_trans.py: -------------------------------------------------------------------------------- 1 | import re 2 | import pathlib 3 | import gevent 4 | from gevent.pool import Pool 5 | from googletrans import Translator 6 | 7 | global sou_file 8 | global des_file 9 | count = 0 10 | global translator 11 | translator = Translator(service_urls=['translate.google.cn']) 12 | global re_text 13 | re_text = re.compile(u"([\u2000-\u206F\u3000-\u303F\u4E00-\u9FBF\uFF00-\uFFEF]+)", re.VERBOSE) 14 | 15 | def tran_sub(line): 16 | global des_file 17 | global count 18 | global translator 19 | count += 1 20 | print("count,%d" % count) 21 | line = line.decode('utf-8') 22 | if line.startswith('Dialogue') and 'student speaking' not in line: 23 | des_file.write(line.encode('utf-8')) 24 | head_str,english_str = tuple(line.rsplit(',,', 1)) 25 | chinese_str = translator.translate(english_str, dest='zh-CN').text 26 | print(chinese_str) 27 | c_line = ',,'.join([head_str,chinese_str+'\n']).replace('English', 'Chinese').replace('您', '你').encode('utf-8') 28 | des_file.write(c_line) 29 | else: 30 | des_file.write(line.encode('utf-8')) 31 | 32 | 33 | def format_sub(line): 34 | global re_text 35 | if line.startswith('Dialogue'): 36 | head_str, text = tuple(line.rsplit(',,', 1)) 37 | if 'Chinese' in head_str: 38 | text = text.decode('utf-8') 39 | format_text = re_text.sub(r' \1 ', text).strip() 40 | des_file.write(',,'.join([head_str, format_text.encode('utf-8') + '\n'])) 41 | else: 42 | des_file.write(line) 43 | 44 | 45 | def main(): 46 | sou_path = u"/Users/eugene/workspace/translationCSAPP/subtitle/English/" 47 | des_path = u"/Users/eugene/workspace/translationCSAPP/subtitle/Chinese_English/" 48 | 49 | filename = u"Lecture 23 Concurrent Programming.ass" 50 | 51 | global sou_file 52 | global des_file 53 | sou_file = open(sou_path+filename, 'rb') 54 | des_file = open(des_path+filename, 'wb+') 55 | # pool = Pool(10) 56 | # pool.map(tran_sub, sou_file) 57 | threads = [gevent.spawn(tran_sub, line) for line in sou_file.readlines()] 58 | gevent.joinall(threads) 59 | sou_file.close() 60 | des_file.close() 61 | 62 | if __name__ == '__main__': 63 | main() 64 | 65 | 66 | # for line in lines: 67 | # if line.startswith('Dialogue:'): 68 | # parts = line.rsplit(',,', 1) 69 | # line = ',,'.join([parts[0], parts[1].lstrip().capitalize()]) 70 | # f.write(line) -------------------------------------------------------------------------------- /subtitle/English/Lecture 02 Bits, Bytes, and Integers.ass: -------------------------------------------------------------------------------- 1 | [Script Info] 2 | ; Script generated by Aegisub 3.2.2 3 | ; http://www.aegisub.org/ 4 | Title: Default Aegisub file 5 | ScriptType: v4.00+ 6 | WrapStyle: 0 7 | ScaledBorderAndShadow: yes 8 | YCbCr Matrix: TV.601 9 | PlayResX: 1280 10 | PlayResY: 720 11 | 12 | [Aegisub Project Garbage] 13 | Last Style Storage: zh 14 | Audio File: ../../../Desktop/csapp/Lecture 02 Bits, Bytes, and Integers.mp4 15 | Video File: ../../../Desktop/csapp/Lecture 02 Bits, Bytes, and Integers.mp4 16 | Video AR Mode: 4 17 | Video AR Value: 1.777778 18 | Video Zoom Percent: 1.000000 19 | Video Position: 12296 20 | 21 | [V4+ Styles] 22 | Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding 23 | Style: Chinese,Source Han Sans CN,34,&H00FFFF00,&H00FFFFFF,&H00989916,&H00FFFFFF,0,0,0,0,100,100,0,0,1,2,0.2,2,10,10,10,1 24 | Style: English,Source Han Sans CN,30,&H00FFFFFF,&H00412A2C,&H00412A2C,&H00412A2C,0,0,0,0,100,100,0,0,1,2,0.5,2,10,10,10,1 25 | 26 | [Events] 27 | Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text 28 | Dialogue: 0,0:00:00.00,0:00:04.68,English,,0,0,0,,I see a lot of people figure it out to come early so good see you 29 | Dialogue: 0,0:00:05.38,0:00:08.80,English,,0,0,0,,So as you recall,my name is Randy Bryant 30 | Dialogue: 0,0:00:08.80,0:00:12.36,English,,0,0,0,,And I'm co-instructor of this course along with Dave Hallaron 31 | Dialogue: 0,0:00:12.80,0:00:22.66,English,,0,0,0,,And for the next couple lectures the first part of this course really will be talking about a sort of data representations 32 | Dialogue: 0,0:00:22.66,0:00:28.30,English,,0,0,0,,In particular how numbers are represented in different forms and some of the properties and you saw that 33 | Dialogue: 0,0:00:29.02,0:00:31.84,English,,0,0,0,,When I talked last week I showed you things like 34 | Dialogue: 0,0:00:31.84,0:00:36.38,English,,0,0,0,,You can multiply some numbers together that are positive and get negative result 35 | Dialogue: 0,0:00:36.38,0:00:41.46,English,,0,0,0,,So what we want to understand is what is the bit level representation of numbers 36 | Dialogue: 0,0:00:41.90,0:00:47.28,English,,0,0,0,,And how does that affect some of the properties you have when you operate them on 37 | Dialogue: 0,0:00:47.28,0:00:51.12,English,,0,0,0,, and especially looking at the corner cases when things overflow 38 | Dialogue: 0,0:00:51.50,0:00:54.08,English,,0,0,0,,We sort of don't do what, you might expect them to do 39 | Dialogue: 0,0:00:55.04,0:00:57.44,English,,0,0,0,, So we'll start off with very basic stuff of 40 | Dialogue: 0,0:00:57.44,0:01:03.84,English,,0,0,0,,How numbers are represented especially integer valued numbers are represented in bits 41 | Dialogue: 0,0:01:05.82,0:01:13.72,English,,0,0,0,,Um so I think you pretty well figured out in this world that the whole digital world is sort of based on on binary values 42 | Dialogue: 0,0:01:14.48,0:01:21.98,English,,0,0,0,,And that wasn't always the case I mean since humans have ten fingers and ten toes 43 | Dialogue: 0,0:01:22.26,0:01:25.04,English,,0,0,0,,A lot of the world was based on the decimal system 44 | Dialogue: 0,0:01:25.52,0:01:38.28,English,,0,0,0,,And it was really only and in fact the first electronic computer the ENIAC built in University of Pennsylvania basically encoded did all of its arithmetic using base ten 45 | Dialogue: 0,0:01:38.60,0:01:42.82,English,,0,0,0,,They had ten vacuum tubes per digit they wanted to represent 46 | Dialogue: 0,0:01:43.36,0:01:50.74,English,,0,0,0,,So they basically turned on or off those tubes to represent which of the ten possible digits you could want 47 | Dialogue: 0,0:01:51.18,0:01:56.26,English,,0,0,0,,And it really didn't come to people until later than that 48 | Dialogue: 0,0:01:56.52,0:02:01.58,English,,0,0,0,,So that's 1948 that they really should just think about base two for everything 49 | Dialogue: 0,0:02:04.06,0:02:14.00,English,,0,0,0,,And the reason why bits are great is in the digital world you can sort of take what otherwise an analog signal and quantify it 50 | Dialogue: 0,0:02:14.36,0:02:17.56,English,,0,0,0,, And just say I'm going to say that one range of values 51 | Dialogue: 0,0:02:17.56,0:02:21.18,English,,0,0,0,, Let's say it's a low voltage I'm going to call that a zero 52 | Dialogue: 0,0:02:21.46,0:02:24.52,English,,0,0,0,,And a high range of values I'm going to call it a one 53 | Dialogue: 0,0:02:24.98,0:02:31.18,English,,0,0,0,, And if there's noise or imperfections in the circuit or anything going on 54 | Dialogue: 0,0:02:31.76,0:02:37.78,English,,0,0,0,,As long as that doesn't exceed these bit these thresholds you've set up 55 | Dialogue: 0,0:02:38.18,0:02:40.38,English,,0,0,0,,Then you'll get a nice clean signal out of it 56 | Dialogue: 0,0:02:40.38,0:02:45.06,English,,0,0,0,,And that's the main advantage of digital processing over analog processing 57 | Dialogue: 0,0:02:46.80,0:02:50.10,English,,0,0,0,, And so that's sort of at the core why everything we do 58 | Dialogue: 0,0:02:50.10,0:02:52.14,English,,0,0,0,, And especially for storing information 59 | Dialogue: 0,0:02:52.18,0:03:00.10,English,,0,0,0,,It turns out it's much easier to store one bit of information or a digital value than it is to store an analog value 60 | Dialogue: 0,0:03:02.10,0:03:09.28,English,,0,0,0,,And sorry this kind of slides went a little crazy on animations 61 | Dialogue: 0,0:03:09.56,0:03:15.42,English,,0,0,0,,So the point is that we represent all the numbers in a computer as sets of bits 62 | Dialogue: 0,0:03:15.42,0:03:18.24,English,,0,0,0,,And I think you generally understand that fairly well 63 | Dialogue: 0,0:03:18.68,0:03:23.98,English,,0,0,0,,And so of course the familiar binary representation of integers which we'll go over today 64 | Dialogue: 0,0:03:24.34,0:03:32.87,English,,0,0,0,, Just uses a bit position for each power of two we can also represent values that are fractional 65 | Dialogue: 0,0:03:32.96,0:03:35.26,English,,0,0,0,,And we'll talk about that a week from today 66 | Dialogue: 0,0:03:35.26,0:03:41.04,English,,0,0,0,,When we do floating-point numbers where what you do is to the right of the binary point 67 | Dialogue: 0,0:03:41.18,0:03:46.60,English,,0,0,0,,So this is no longer a decimal point it's a binary point 68 | Dialogue: 0,0:03:47.20,0:03:52.44,English,,0,0,0,,And so something to the left of that would have a weight 2^0 69 | Dialogue: 0,0:03:53.84,0:03:56.62,English,,0,0,0,,And the next one over would have weight 2^0 70 | Dialogue: 0,0:03:57.04,0:04:03.88,English,,0,0,0,,But what you do is as you go to the right that adds weight 2^-1,2^-2 71 | Dialogue: 0,0:04:03.88,0:04:10.34,English,,0,0,0,, In other words this is 1,this is 2, this is 1/2 and this is 1/4 72 | Dialogue: 0,0:04:11.44,0:04:15.70,English,,0,0,0,,So we can represent just like you do the decimal representation of fractions 73 | Dialogue: 0,0:04:16.06,0:04:18.44,English,,0,0,0,,We can do the binary representation of fractions 74 | Dialogue: 0,0:04:18.44,0:04:22.22,English,,0,0,0,, And that's the core of floating-point number of representations 75 | Dialogue: 0,0:04:23.94,0:04:35.06,English,,0,0,0,,And so it gets very annoying if you have say 32 or even 64-bit numbers to be writing the strings of 1 and 0 out 76 | Dialogue: 0,0:04:35.42,0:04:45.54,English,,0,0,0,,And so what we use,and what's become largely the most common is to group collections of 4bits at a time into 77 | Dialogue: 0,0:04:45.98,0:04:50.90,English,,0,0,0,,And then represent that in base 16 or what's known as hexadecimal representation 78 | Dialogue: 0,0:04:51.28,0:04:56.12,English,,0,0,0,, Using the letters A through F as values 10 through 15 79 | Dialogue: 0,0:04:56.12,0:05:00.78,English,,0,0,0,,And you'll spend a lot of time staring at hex decimal numbers this year 80 | Dialogue: 0,0:05:01.10,0:05:05.66,English,,0,0,0,,And you'll get pretty good at being able to look at a hex number and just write it out in binary 81 | Dialogue: 0,0:05:06.20,0:05:09.82,English,,0,0,0,,The way I do it just to tell you is 82 | Dialogue: 0,0:05:10.56,0:05:22.74,English,,0,0,0,,I mean I've got the values from 0 to 9 wired down pretty well 83 | Dialogue: 0,0:05:24.10,0:05:28.90,English,,0,0,0,,And then I keep track of a few special cases 1010 is A 84 | Dialogue: 0,0:05:29.78,0:05:37.94,English,,0,0,0,,1100 is C and 1111 is F 85 | Dialogue: 0,0:05:39.00,0:05:45.46,English,,0,0,0,, And for B,D and E I kind of interpolate between those 86 | Dialogue: 0,0:05:45.46,0:05:49.10,English,,0,0,0,,So if you want to develop that skill that's the way you can do it 87 | Dialogue: 0,0:05:49.10,0:05:54.26,English,,0,0,0,,...an HDMI to what... 88 | Dialogue: 0,0:05:54.48,0:05:57.24,English,,0,0,0,,-No,I don't think there's any connector here. -no 89 | Dialogue: 0,0:06:03.36,0:06:06.68,English,,0,0,0,, So that's something you're going to end up wanting to be able to do 90 | Dialogue: 0,0:06:08.08,0:06:10.74,English,,0,0,0,,So in C we don't... 91 | Dialogue: 0,0:06:12.14,0:06:18.30,English,,0,0,0,,In most declarations you don't actually are told exactly how many bytes 92 | Dialogue: 0,0:06:18.30,0:06:20.30,English,,0,0,0,,A byte is 8 bits 93 | Dialogue: 0,0:06:20.96,0:06:23.14,English,,0,0,0,,Each data value is represented as 94 | Dialogue: 0,0:06:23.52,0:06:30.46,English,,0,0,0,,And that's partly C was designed actually back when microprocessors only had 16-bit words 95 | Dialogue: 0,0:06:30.46,0:06:32.38,English,,0,0,0,, It was actually before microprocessors 96 | Dialogue: 0,0:06:32.90,0:06:40.20,English,,0,0,0,, So 16-bit words were a fairly standard and over time that's expanded from 16 to 32 to now 64 97 | Dialogue: 0,0:06:40.70,0:06:44.36,English,,0,0,0,,And so C rather than a sort of an advanced thing 98 | Dialogue: 0,0:06:44.36,0:06:49.34,English,,0,0,0,,Here is how many bytes every value will have has these slightly ambiguous terms 99 | Dialogue: 0,0:06:49.84,0:06:53.20,English,,0,0,0,, That vary actually from one machine to the next 100 | Dialogue: 0,0:06:55.26,0:07:01.00,English,,0,0,0,,And if you're a very careful C programmer you have to anticipate that some 101 | Dialogue: 0,0:07:01.44,0:07:09.80,English,,0,0,0,,But what won't deal with is x86-64 is the class of machines will be working with exclusively this term 102 | Dialogue: 0,0:07:10.10,0:07:13.22,English,,0,0,0,,And so you can see that when you declare something to be a care 103 | Dialogue: 0,0:07:13.80,0:07:17.68,English,,0,0,0,, Sometimes people call it a char that's a 1 byte value 104 | Dialogue: 0,0:07:17.88,0:07:20.66,English,,0,0,0,,A short is 16 bits 105 | Dialogue: 0,0:07:21.58,0:07:29.76,English,,0,0,0,,An int is 32 and if you want to get all 64 bits you have to declare it to be a long 106 | Dialogue: 0,0:07:32.20,0:07:35.88,English,,0,0,0,,And then again there's two different representations of floating-point there's 4 byte 107 | Dialogue: 0,0:07:35.88,0:07:39.34,English,,0,0,0,, Or 32 bit of floating-point numbers and 64 bit 108 | Dialogue: 0,0:07:39.84,0:07:47.48,English,,0,0,0,,There's also a slightly obscure holdover from ancient days of floating-point 109 | Dialogue: 0,0:07:47.48,0:07:54.24,English,,0,0,0,,Where there's a special representation in Intel machines that uses a 10 bit or 80 bit representation 110 | Dialogue: 0,0:07:54.70,0:08:03.68,English,,0,0,0,, And when you use that on a 64-bit machine they sort of waste an extra 6 bytes out of that 111 | Dialogue: 0,0:08:03.68,0:08:07.88,English,,0,0,0,,So that everything is aligned in 16 byte increments 112 | Dialogue: 0,0:08:08.80,0:08:17.86,English,,0,0,0,, The other thing and this is an important feature is any address is find to be the sort of the word size of the machine 113 | Dialogue: 0,0:08:17.86,0:08:25.98,English,,0,0,0,, When they say it's a 64-bit machine,what they really mean is that the addresses are 64-bit values or 8-byte values 114 | Dialogue: 0,0:08:26.28,0:08:31.54,English,,0,0,0,,And that's different for example if you use a older machine a 32-bit machine 115 | Dialogue: 0,0:08:31.56,0:08:34.06,English,,0,0,0,,Those will only be 32-bit addresses 116 | Dialogue: 0,0:08:37.42,0:08:48.14,English,,0,0,0,,So the basis sent I imagine you've had this at some point of how do we then think about bits is based on boolean algebra 117 | Dialogue: 0,0:08:48.40,0:08:55.14,English,,0,0,0,, Which is actually comes from the 1890s that a guy named George Boole 118 | Dialogue: 0,0:08:55.38,0:09:02.44,English,,0,0,0,,Who recognized is sort of relation between what we'd call bits but they weren't called bits back then 119 | Dialogue: 0,0:09:02.98,0:09:08.76,English,,0,0,0,,0,1 and logic are basically truth values in logic 120 | Dialogue: 0,0:09:09.06,0:09:13.26,English,,0,0,0,,I thinking of an algebra sort of a structured set of operations 121 | Dialogue: 0,0:09:13.26,0:09:19.08,English,,0,0,0,, You could apply that would capture some of the concepts that people assume in logic 122 | Dialogue: 0,0:09:19.56,0:09:24.14,English,,0,0,0,,So for example if we think of 1 being true and 0 being false 123 | Dialogue: 0,0:09:24.80,0:09:31.06,English,,0,0,0,,Then the and operation is true if both of the inputs the both of the arguments are true 124 | Dialogue: 0,0:09:31.48,0:09:33.00,English,,0,0,0,,so we get this chart here 125 | Dialogue: 0,0:09:33.00,0:09:38.86,English,,0,0,0,,Similarly the or operation is true if either input is true or 1 126 | Dialogue: 0,0:09:39.30,0:09:43.04,English,,0,0,0,,The NOT is just to flip the bit 127 | Dialogue: 0,0:09:43.42,0:09:49.36,English,,0,0,0,,And then the exclusive-or is what you get when you say it's one or the other but not both 128 | Dialogue: 0,0:09:49.70,0:09:52.26,English,,0,0,0,, And so it has this representation 129 | Dialogue: 0,0:09:52.56,0:09:59.74,English,,0,0,0,, So just as a bit of history it was a master's degree student at MIT named Claude Shannon 130 | Dialogue: 0,0:10:00.28,0:10:07.02,English,,0,0,0,, Who had taken a course in logic as an undergraduate at University of Michigan 131 | Dialogue: 0,0:10:07.80,0:10:12.86,English,,0,0,0,,And he was the one who made the connection between thinking about 132 | Dialogue: 0,0:10:12.86,0:10:20.34,English,,0,0,0,,This this what was at the time very obscure branch of something a rather of logic 133 | Dialogue: 0,0:10:20.52,0:10:24.30,English,,0,0,0,,And applying it to digital systems back in an era when they actually built 134 | Dialogue: 0,0:10:24.66,0:10:27.44,English,,0,0,0,, These things out of electromechanical noise 135 | Dialogue: 0,0:10:28.12,0:10:36.88,English,,0,0,0,, And so his master's thesis is probably the most impactful master's thesis in the history of humankind 136 | Dialogue: 0,0:10:37.58,0:10:41.96,English,,0,0,0,,And he always wonder well what did they do before that then 137 | Dialogue: 0,0:10:41.96,0:10:44.18,English,,0,0,0,,You know how do they even think about these things 138 | Dialogue: 0,0:10:44.72,0:10:49.84,English,,0,0,0,,Anyways the idea of applying this algebra then to bits is not 139 | Dialogue: 0,0:10:50.40,0:10:54.34,English,,0,0,0,,Something that should have been true since the the world began 140 | Dialogue: 0,0:10:54.36,0:10:57.20,English,,0,0,0,, Something that's a relatively modern concept 141 | Dialogue: 0,0:10:57.86,0:11:06.82,English,,0,0,0,,Now what's an important thing that might be less obvious is we can also do these over words 142 | Dialogue: 0,0:11:06.82,0:11:13.42,English,,0,0,0,,We can do these boolean operations where we apply them on each successive bit in that word 143 | Dialogue: 0,0:11:13.70,0:11:18.58,English,,0,0,0,,And these symbols we use the ampersand vertical bar carrot and tilde 144 | Dialogue: 0,0:11:18.80,0:11:22.54,English,,0,0,0,, are actually the ones that see use is to represent these operations 145 | Dialogue: 0,0:11:23.16,0:11:28.46,English,,0,0,0,,And so again if we look at here the 1 is only if both of the values 1 146 | Dialogue: 0,0:11:28.98,0:11:33.38,English,,0,0,0,,And the for the or for the and for the one 147 | Dialogue: 0,0:11:33.72,0:11:36.02,English,,0,0,0,, 'Or' its if either of them are 1 148 | Dialogue: 0,0:11:36.58,0:11:40.46,English,,0,0,0,,The exclusive or if 1 is 1 and the other is zero 149 | Dialogue: 0,0:11:40.58,0:11:43.74,English,,0,0,0,,And tilde is just to invert the bits of it 150 | Dialogue: 0,0:11:43.74,0:11:49.16,English,,0,0,0,,So again we will spend a lot of time making use of the fact that in C 151 | Dialogue: 0,0:11:49.16,0:11:51.48,English,,0,0,0,,And this is one of the features to C that people like 152 | Dialogue: 0,0:11:51.78,0:11:57.16,English,,0,0,0,,is that you can do these sort of very low level of bit manipulations directly in the language 153 | Dialogue: 0,0:11:58.28,0:11:59.50,English,,0,0,0,,and um 154 | Dialogue: 0,0:12:00.60,0:12:04.34,English,,0,0,0,,This actually turns out to be useful in practice 155 | Dialogue: 0,0:12:04.34,0:12:08.66,English,,0,0,0,, And it's sort of implicit of a way of representing sets of values 156 | Dialogue: 0,0:12:08.76,0:12:13.12,English,,0,0,0,,So this example is a imagine we want to represent sets 157 | Dialogue: 0,0:12:13.78,0:12:18.40,English,,0,0,0,,Where the elements of the set are numbers ranging between 0 and 7 158 | Dialogue: 0,0:12:18.92,0:12:23.92,English,,0,0,0,,So 1 byte is enough to capture eight cases 159 | Dialogue: 0,0:12:24.22,0:12:29.00,English,,0,0,0,,And we'll just if we number the bits and we number them from right to left 160 | Dialogue: 0,0:12:29.58,0:12:36.96,English,,0,0,0,,So this is bit 0 so that would represent whether or not the value 0 is an element of the set 161 | Dialogue: 0,0:12:37.58,0:12:41.06,English,,0,0,0,,And similarly here you'll see 0,1,2,3 162 | Dialogue: 0,0:12:41.06,0:12:47.84,English,,0,0,0,,So we're saying that bit 3 being one here means 3 is an element of the set and so forth 163 | Dialogue: 0,0:12:48.40,0:12:52.30,English,,0,0,0,,and the 164 | Dialogue: 0,0:12:54.74,0:12:59.32,English,,0,0,0,,So the idea is then the AND operation becomes like set intersection 165 | Dialogue: 0,0:12:59.66,0:13:02.30,English,,0,0,0,, The OR operation becomes like set Union 166 | Dialogue: 0,0:13:02.66,0:13:08.70,English,,0,0,0,,And the X-OR operation is what's called symmetric difference 167 | Dialogue: 0,0:13:11.40,0:13:14.84,English,,0,0,0,,And so these are actually and ~ is like set complement 168 | Dialogue: 0,0:13:14.86,0:13:18.28,English,,0,0,0,,So these are actually very common for example 169 | Dialogue: 0,0:13:18.54,0:13:27.80,English,,0,0,0,,There are operations you'll learn later when we look at a file i/o 170 | Dialogue: 0,0:13:27.98,0:13:35.36,English,,0,0,0,,About i/o that you can track I want to know which set of possible inputs to the system 171 | Dialogue: 0,0:13:35.36,0:13:40.04,English,,0,0,0,,think of different network connections have an input ready for me to read 172 | Dialogue: 0,0:13:40.80,0:13:44.04,English,,0,0,0,,And there is a data structure that 173 | Dialogue: 0,0:13:44.78,0:13:47.60,English,,0,0,0,,It's sort of hidden away among some seeing library calls 174 | Dialogue: 0,0:13:47.60,0:13:52.20,English,,0,0,0,, But it basically is using exactly this representation about a thousand 175 | Dialogue: 0,0:13:52.50,0:13:55.90,English,,0,0,0,,A bits worth of information to represent these sets 176 | Dialogue: 0,0:13:56.54,0:14:00.18,English,,0,0,0,,And do manipulation on those sets so this is a very common 177 | Dialogue: 0,0:14:00.48,0:14:05.48,English,,0,0,0,,And why do we use representation of sets in computer science 178 | Dialogue: 0,0:14:07.98,0:14:15.68,English,,0,0,0,,so as I mentioned those are available directly and C the &,||, ~ and ^ 179 | Dialogue: 0,0:14:16.46,0:14:21.82,English,,0,0,0,,One thing that's really really important and that programmers screw it up all the time 180 | Dialogue: 0,0:14:21.82,0:14:31.12,English,,0,0,0,,Beginning programmers a lot and even experienced programmers from time to time is to mix up the & in the && 181 | Dialogue: 0,0:14:31.12,0:14:34.14,English,,0,0,0,,or the | in the || 182 | Dialogue: 0,0:14:34.88,0:14:39.70,English,,0,0,0,,and the ~ versus the exclamation mark which is often pronounced bang 183 | Dialogue: 0,0:14:40.66,0:14:44.68,English,,0,0,0,,so and the reason 184 | Dialogue: 0,0:14:45.58,0:14:49.00,English,,0,0,0,, So obviously there's sort of a syntactic similarity 185 | Dialogue: 0,0:14:49.00,0:14:51.60,English,,0,0,0,,And there's actually a somewhat of a semantic relation to that 186 | Dialogue: 0,0:14:52.10,0:14:56.74,English,,0,0,0,, This is another kind of AND another kind of OR and another kind of NOT 187 | Dialogue: 0,0:14:57.90,0:15:02.06,English,,0,0,0,,But if you mix and match these you're certainly going to have problems 188 | Dialogue: 0,0:15:02.66,0:15:07.42,English,,0,0,0,,So the || ones aren't thinking about bitwise operations 189 | Dialogue: 0,0:15:07.42,0:15:11.10,English,,0,0,0,,through thinking about something that's either true or false period 190 | Dialogue: 0,0:15:12.18,0:15:17.48,English,,0,0,0,,And in that representation the number 0 is the thing that's false 191 | Dialogue: 0,0:15:17.48,0:15:21.70,English,,0,0,0,,And anything else any other bit pattern is considered to be true 192 | Dialogue: 0,0:15:23.60,0:15:31.72,English,,0,0,0,,The other feature that the || give you is what's called early termination 193 | Dialogue: 0,0:15:32.86,0:15:37.56,English,,0,0,0,,So in particular if we do some examples 194 | Dialogue: 0,0:15:37.78,0:15:48.92,English,,0,0,0,,On the some hex pattern for 1, so this is a not a 0 and so that's considered true 195 | Dialogue: 0,0:15:48.92,0:15:54.02,English,,0,0,0,,In this interpretation and so the the bang of that the not of that is 0 196 | Dialogue: 0,0:15:54.04,0:15:57.36,English,,0,0,0,,The same way if you have 0 the not event is 1 197 | Dialogue: 0,0:15:57.66,0:16:04.18,English,,0,0,0,,And if you apply bang to a number twice you'll get back a 1 unless it was 0 198 | Dialogue: 0,0:16:08.84,0:16:13.04,English,,0,0,0,,And then a simile these patterns here 199 | Dialogue: 0,0:16:13.44,0:16:18.30,English,,0,0,0,,The reason why this returns 1 is because it's considered two cases that are true 200 | Dialogue: 0,0:16:19.88,0:16:24.50,English,,0,0,0,,So it's not doing bitwise operations it's just trying to create true and fault 201 | Dialogue: 0,0:16:24.50,0:16:29.28,English,,0,0,0,,It's interpreting arguments be there true or false and returning either true or false 202 | Dialogue: 0,0:16:29.78,0:16:34.92,English,,0,0,0,,But when it returns true it returns one and not whatever number you happen to give 203 | Dialogue: 0,0:16:35.82,0:16:39.12,English,,0,0,0,,So obviously this is a very different operations 204 | Dialogue: 0,0:16:39.12,0:16:43.72,English,,0,0,0,,Than you have with the single versions of those and 205 | Dialogue: 0,0:16:44.74,0:16:51.66,English,,0,0,0,,But it's easy just because you mentally slip or because you type something wrong to do the wrong thing 206 | Dialogue: 0,0:16:52.18,0:16:56.22,English,,0,0,0,,But in particularly this early termination is something that of course people use a lot 207 | Dialogue: 0,0:16:56.74,0:17:01.04,English,,0,0,0,,If you want to make sure that you're not accessing a null pointer 208 | Dialogue: 0,0:17:01.04,0:17:05.68,English,,0,0,0,, You can test whether that's a null pointer first before accessing it 209 | Dialogue: 0,0:17:05.68,0:17:11.18,English,,0,0,0,,And this if this is 0 or then it will do the the dereferencing of null 210 | Dialogue: 0,0:17:12.12,0:17:15.44,English,,0,0,0,,So it's a fairly useful feature as well 211 | Dialogue: 0,0:17:15.66,0:17:21.38,English,,0,0,0,,So anyways just that's an aside at this level we're mostly looking at bits 212 | Dialogue: 0,0:17:21.38,0:17:24.62,English,,0,0,0,,But just as a programming no don't mix these up 213 | Dialogue: 0,0:17:32.62,0:17:36.68,English,,0,0,0,,The other class of operations will make use of a lot our shifting 214 | Dialogue: 0,0:17:37.08,0:17:42.24,English,,0,0,0,, Which again is not something that you normally sort of as beginning programmers think about too much 215 | Dialogue: 0,0:17:42.92,0:17:47.10,English,,0,0,0,,And if there's a curious feature that a left shifts are always the same 216 | Dialogue: 0,0:17:47.10,0:17:49.20,English,,0,0,0,,But there's two different flavors of right shift 217 | Dialogue: 0,0:17:49.62,0:17:53.72,English,,0,0,0,, And we'll see in a little bit later why there's two different flavors of right shift 218 | Dialogue: 0,0:17:54.90,0:17:58.61,English,,0,0,0,,But um 219 | Dialogue: 0,0:17:59.00,0:18:03.22,English,,0,0,0,,The idea that of shifting is that you have some argument x 220 | Dialogue: 0,0:18:03.22,0:18:08.52,English,,0,0,0,,And you want to shift it some number of positions either to the left or to the right given by y 221 | Dialogue: 0,0:18:09.50,0:18:15.02,English,,0,0,0,,And so when you shift left you just fill in whatever value there was so you pick up the 222 | Dialogue: 0,0:18:15.62,0:18:21.34,English,,0,0,0,,I'm shifting by three,so I'll take the low order five bits move them over three positions 223 | Dialogue: 0,0:18:21.68,0:18:23.30,English,,0,0,0,,Then fill in with a zero 224 | Dialogue: 0,0:18:23.64,0:18:31.55,English,,0,0,0,,And whatever was in the upper positions of that original words they just sort of disappear into nowhere 225 | Dialogue: 0,0:18:32.10,0:18:39.56,English,,0,0,0,,Similarly if I do a right shift I take the upper six bits I move them over to positions and I fill in with zeros 226 | Dialogue: 0,0:18:40.32,0:18:44.96,English,,0,0,0,,So that's a logical shift and that's well it's logic 227 | Dialogue: 0,0:18:45.44,0:18:48.00,English,,0,0,0,,There's another flavor called the arithmetic shift 228 | Dialogue: 0,0:18:48.00,0:18:54.38,English,,0,0,0,,Which it differs in that the rule for what bits you fill in with are not based on the are 229 | Dialogue: 0,0:18:55.70,0:19:01.56,English,,0,0,0,,not zeros necessarily but it's whatever the most significant bit was in the original value 230 | Dialogue: 0,0:19:02.00,0:19:04.90,English,,0,0,0,,So it doesn't matter here because the most significant bit was zero 231 | Dialogue: 0,0:19:04.90,0:19:11.74,English,,0,0,0,, But you'll see in the case here of where the leading bit was a 1 232 | Dialogue: 0,0:19:12.80,0:19:18.68,English,,0,0,0,, That when I shift it to the right arithmetic we I'll fill it in with 1 233 | Dialogue: 0,0:19:19.40,0:19:25.38,English,,0,0,0,,And that'll make sense more when we understand how negative numbers get represented in a machine 234 | Dialogue: 0,0:19:25.98,0:19:28.82,English,,0,0,0,,And that's the purpose of it and why it's called arithmetic 235 | Dialogue: 0,0:19:31.60,0:19:37.54,English,,0,0,0,,Um the other thing is confusing to people is 236 | Dialogue: 0,0:19:37.80,0:19:44.80,English,,0,0,0,,What should happen if you say I want to shift an 8-bit number 8 positions to the left 237 | Dialogue: 0,0:19:54.60,0:19:58.92,English,,0,0,0,,And X is a single byte what do you think you should get 238 | Dialogue: 0,0:20:02.84,0:20:07.86,English,,0,0,0,, Zero that would be a pretty logical thing you kind of shift all those bits out you fill them with zeros 239 | Dialogue: 0,0:20:08.40,0:20:13.12,English,,0,0,0,,On most machines you'll get whatever x was 240 | Dialogue: 0,0:20:17.38,0:20:21.88,English,,0,0,0,,Because what will do is it will compute this number mod 8 241 | Dialogue: 0,0:20:25.90,0:20:28.64,English,,0,0,0,,And the reason that happens is if you think about it 242 | Dialogue: 0,0:20:28.64,0:20:34.02,English,,0,0,0,,It's looking at just the lower two three bits of the shift amount and ignoring all the rest 243 | Dialogue: 0,0:20:34.26,0:20:36.90,English,,0,0,0,, So that's effectively like module 8 244 | Dialogue: 0,0:20:37.76,0:20:41.38,English,,0,0,0,,So that's just a warning I and some machines it does 245 | Dialogue: 0,0:20:41.38,0:20:44.44,English,,0,0,0,,What you just thought it should and other machines it does this 246 | Dialogue: 0,0:20:44.88,0:20:50.12,English,,0,0,0,,And so there's no no guarantee and see that it will be one way or the other 247 | Dialogue: 0,0:20:52.80,0:20:58.70,English,,0,0,0,,Same with if you try to shift left by a negative number that might be logically 248 | Dialogue: 0,0:20:58.70,0:21:02.88,English,,0,0,0,,Well I guess you really want to shift right then but that usually doesn't work either 249 | Dialogue: 0,0:21:05.40,0:21:09.06,English,,0,0,0,,So now let's talk about number representations 250 | Dialogue: 0,0:21:09.68,0:21:10.32,English,,0,0,0,,And 251 | Dialogue: 0,0:21:12.10,0:21:18.24,English,,0,0,0,,This is sort of a very core its idea that you have to really have wired in you 252 | Dialogue: 0,0:21:18.56,0:21:22.20,English,,0,0,0,,And I'm going to illustrate it with some examples 253 | Dialogue: 0,0:21:27.74,0:21:35.30,English,,0,0,0,,So the these two equations that are everything that we'll talk about sort of stems from them 254 | Dialogue: 0,0:21:35.98,0:21:38.64,English,,0,0,0,,So one is if you have an unsigned number 255 | Dialogue: 0,0:21:39.22,0:21:45.18,English,,0,0,0,,Then basically...it keeps jumping on me 256 | Dialogue: 0,0:21:46.78,0:21:52.42,English,,0,0,0,,If you have an unsigned number then this is just the conversion 257 | Dialogue: 0,0:21:52.42,0:22:00.56,English,,0,0,0,,B2U means from a bit level representation to an unsigned number of some bit pattern 258 | Dialogue: 0,0:22:00.56,0:22:04.68,English,,0,0,0,,It just says we'll just add up the sum of the weighted bits 259 | Dialogue: 0,0:22:04.94,0:22:07.86,English,,0,0,0,,Where each bit is weighted by a power of two 260 | Dialogue: 0,0:22:08.48,0:22:10.88,English,,0,0,0,, And the only difference when we look at two's complement 261 | Dialogue: 0,0:22:10.88,0:22:14.74,English,,0,0,0,,Which is a way to represent both negative and positive numbers 262 | Dialogue: 0,0:22:15.00,0:22:18.86,English,,0,0,0,,It's we'll consider the most significant bit to be what's called the sign bit 263 | Dialogue: 0,0:22:19.60,0:22:21.66,English,,0,0,0,,So it will have a negative value 264 | Dialogue: 0,0:22:22.10,0:22:26.68,English,,0,0,0,,So let me just illustrate this with I'll use some running examples 265 | Dialogue: 0,0:22:26.68,0:22:34.90,English,,0,0,0,,We'll just use five bit numbers just as a way it really helps often if you're trying to understand this stuff to do it for some smaller cases 266 | Dialogue: 0,0:22:36.10,0:22:39.38,English,,0,0,0,,So if we think about bit positions 267 | Dialogue: 0,0:22:49.38,0:22:51.28,English,,0,0,0,,zero through four 268 | Dialogue: 0,0:22:59.18,0:23:04.70,English,,0,0,0,,Then those represent of different powers of two weights of as I've shown 269 | Dialogue: 0,0:23:05.40,0:23:08.04,English,,0,0,0,,And so now if we take some bit a pattern 270 | Dialogue: 0,0:23:18.92,0:23:19.96,English,,0,0,0,,Like so 271 | Dialogue: 0,0:23:20.34,0:23:26.32,English,,0,0,0,,So that's what I'll call X and I want to convert that to an unsigned number 272 | Dialogue: 0,0:23:26.98,0:23:37.32,English,,0,0,0,,I will just combine 8 + 4 + 1 and I'll get 13 273 | Dialogue: 0,0:23:38.18,0:23:38.76,English,,0,0,0,,all right 274 | Dialogue: 0,0:23:39.20,0:23:46.36,English,,0,0,0,,So that's all that equation says the left hand equations just take the the bit positions that are ones 275 | Dialogue: 0,0:23:46.86,0:23:48.97,English,,0,0,0,,Use the corresponding power of 2 and you're done 276 | Dialogue: 0,0:23:50.18,0:23:53.56,English,,0,0,0,,And similarly if I have a number where there's a leading bit 277 | Dialogue: 0,0:24:01.48,0:24:09.06,English,,0,0,0,,It will be 16 + 4 + 2 so that will be 22 278 | Dialogue: 0,0:24:11.20,0:24:13.26,English,,0,0,0,,And so that's the unsigned case 279 | Dialogue: 0,0:24:15.24,0:24:18.32,English,,0,0,0,,And the sign case is the same idea 280 | Dialogue: 0,0:24:18.86,0:24:26.02,English,,0,0,0,,Except that most significant debt has a negative value 281 | Dialogue: 0,0:24:27.08,0:24:29.42,English,,0,0,0,,So it will still this is i 282 | Dialogue: 0,0:24:32.70,0:24:36.50,English,,0,0,0,,And our weights will be 1,2,4,8 283 | Dialogue: 0,0:24:36.54,0:24:38.40,English,,0,0,0,,But this will be -16 284 | Dialogue: 0,0:24:39.54,0:24:43.76,English,,0,0,0,,So that's what the equation on the right is saying this fit 285 | Dialogue: 0,0:24:44.80,0:24:47.68,English,,0,0,0,,Now we're going to change it from being a negative number to a positive 286 | Dialogue: 0,0:24:48.42,0:24:52.32,English,,0,0,0,,So obviously if I have this is my bit pattern it's going to be the same because 287 | Dialogue: 0,0:24:52.78,0:25:01.16,English,,0,0,0,,The other bits stayed at the same so let's do it for this case of 10110 288 | Dialogue: 0,0:25:03.12,0:25:10.04,English,,0,0,0,,So that will be -16 + 4 + 2 = -10 289 | Dialogue: 0,0:25:13.92,0:25:17.78,English,,0,0,0,,So you see in this case we have the same bit pattern 290 | Dialogue: 0,0:25:18.86,0:25:24.32,English,,0,0,0,, It's just if we interpret it you know how we think about what number this represents 291 | Dialogue: 0,0:25:24.64,0:25:30.92,English,,0,0,0,,Then in one case it's a positive number 22 in another case it's a negative number -10 292 | Dialogue: 0,0:25:32.50,0:25:34.80,English,,0,0,0,, And that's what these equations you see 293 | Dialogue: 0,0:25:40.16,0:25:45.04,English,,0,0,0,,And so the most significant bit is sometimes called the sign bit because 294 | Dialogue: 0,0:25:45.04,0:25:47.46,English,,0,0,0,,If it's a 1 the number is going to be negative 295 | Dialogue: 0,0:25:51.22,0:25:55.72,English,,0,0,0,, So let's sort of think about 296 | Dialogue: 0,0:25:57.94,0:26:01.40,English,,0,0,0,,What extreme,what are the sort of extreme ranges of numbers 297 | Dialogue: 0,0:26:01.40,0:26:03.62,English,,0,0,0,,We can get with these two different representations 298 | Dialogue: 0,0:26:12.48,0:26:16.24,English,,0,0,0,, So obviously if these are all zeros my number is going to equal zero 299 | Dialogue: 0,0:26:20.00,0:26:34.42,English,,0,0,0,,And if it's all 1 it will be 16 + 8 + 4 + 2 + 1 will be 31 300 | Dialogue: 0,0:26:35.86,0:26:39.62,English,,0,0,0,,And over here for the two's complement 301 | Dialogue: 0,0:26:41.68,0:26:51.82,English,,0,0,0,,The smallest number,well the largest number will actually be let me do it this way 302 | Dialogue: 0,0:26:52.02,0:26:56.74,English,,0,0,0,,Actually the most negative number so the smallest number and the strictest sense of the word is 303 | Dialogue: 0,0:26:57.56,0:27:03.20,English,,0,0,0,, is this it's -16. you can argue this by the way 304 | Dialogue: 0,0:27:03.48,0:27:08.54,English,,0,0,0,,This is the only bit that has a negative weight all the other ones have positive ones 305 | Dialogue: 0,0:27:08.54,0:27:13.16,English,,0,0,0,,So certainly one and all the rest being zeros is going to be the smallest number 306 | Dialogue: 0,0:27:13.60,0:27:16.26,English,,0,0,0,,And similarly the largest number you can represent 307 | Dialogue: 0,0:27:20.44,0:27:27.32,English,,0,0,0,,We'll be 8 + 4 + 2 + 1 which is 15 308 | Dialogue: 0,0:27:31.42,0:27:33.80,English,,0,0,0,, And so we call this number UMax 309 | Dialogue: 0,0:27:38.52,0:27:41.06,English,,0,0,0,,And we call this number TMax 310 | Dialogue: 0,0:27:43.72,0:27:45.54,English,,0,0,0,,And we call this number TMin 311 | Dialogue: 0,0:27:48.58,0:27:51.36,English,,0,0,0,,So there's a few things to observe about these numbers 312 | Dialogue: 0,0:27:55.04,0:27:58.42,English,,0,0,0,,That remember this is a 5-bit word size right so 313 | Dialogue: 0,0:28:00.62,0:28:06.23,English,,0,0,0,,You'll see that 31 is pretty close to 32 right 314 | Dialogue: 0,0:28:06.23,0:28:10.82,English,,0,0,0,,In fact it's 2^5-1 315 | Dialogue: 0,0:28:12.56,0:28:17.04,English,,0,0,0,,And in general if it's a five and that's for a 5-bit word size 316 | Dialogue: 0,0:28:17.04,0:28:27.14,English,,0,0,0,,So you would say in general it will have value 2^w if I have a W bit number minus 1 and that's what this shows 317 | Dialogue: 0,0:28:31.04,0:28:36.96,English,,0,0,0,,And similarly over here this is -2^4 318 | Dialogue: 0,0:28:40.38,0:28:46.74,English,,0,0,0,,And so we'd say in general that will be -2^w if it's a W bit number minus 1 319 | Dialogue: 0,0:28:49.22,0:28:54.18,English,,0,0,0,,Right all these make sense by the way you'll notice one other feature is 320 | Dialogue: 0,0:28:58.60,0:29:06.74,English,,0,0,0,, A whole string of ones like this if you sum up those digits 8 + 4 + 2 + 1 321 | Dialogue: 0,0:29:07.12,0:29:11.84,English,,0,0,0,, Will be 1 less than the next bit position up 322 | Dialogue: 0,0:29:13.22,0:29:18.64,English,,0,0,0,,And you can think about that if you were to count this number 323 | Dialogue: 0,0:29:18.94,0:29:25.16,English,,0,0,0,,If you were to increment this number by 1 you'd get 1 1 is 0 carry 1 and so forth 324 | Dialogue: 0,0:29:25.22,0:29:29.42,English,,0,0,0,,And you'd carry that value up to this position so these various ways you can think about that 325 | Dialogue: 0,0:29:31.52,0:29:37.38,English,,0,0,0,,And then similarly this number is 2^4-1 326 | Dialogue: 0,0:29:38.52,0:29:42.98,English,,0,0,0,,And so that's equal to 2^(w-1) - 1 327 | Dialogue: 0,0:29:47.76,0:29:49.40,English,,0,0,0,,As is shown here 328 | Dialogue: 0,0:29:51.98,0:29:59.02,English,,0,0,0,, So there's a lot of the book goes through formulas and does derivation 329 | Dialogue: 0,0:29:59.60,0:30:03.68,English,,0,0,0,, But if you just think about it in these smaller scale ways 330 | Dialogue: 0,0:30:04.10,0:30:10.10,English,,0,0,0,, The intuition is pretty easy to get and don't get lost in in formulas when 331 | Dialogue: 0,0:30:10.26,0:30:13.92,English,,0,0,0,,Really at the gut level it's a fairly straightforward sort of ideas 332 | Dialogue: 0,0:30:15.00,0:30:18.52,English,,0,0,0,, Or if you ever see some confusions and you're confused 333 | Dialogue: 0,0:30:19.12,0:30:22.25,English,,0,0,0,, Try out some small examples and see what they're saying 334 | Dialogue: 0,0:30:22.90,0:30:31.60,English,,0,0,0,,Another interesting number in the world of two's complement is what happens when you have all ones in your bit patterns 335 | Dialogue: 0,0:30:35.80,0:30:45.66,English,,0,0,0,,And that will have mate -16 + 8 + 4 + 2 + 1 and that will equal -1 336 | Dialogue: 0,0:30:47.80,0:30:53.85,English,,0,0,0,,So the bit pattern all ones is always a -1 in this representation 337 | Dialogue: 0,0:30:54.04,0:30:59.74,English,,0,0,0,,I should mention two's complement is not the only way to represent a positive and negative numbers 338 | Dialogue: 0,0:30:59.74,0:31:01.48,English,,0,0,0,,what's sometimes called signed numbers 339 | Dialogue: 0,0:31:01.78,0:31:06.62,English,,0,0,0,,But it's so universal that you'll hardly ever encounter another case 340 | Dialogue: 0,0:31:07.12,0:31:14.62,English,,0,0,0,, So if you understand two's complement you have a pretty good understanding of what really is going on 341 | Dialogue: 0,0:31:22.06,0:31:26.90,English,,0,0,0,,So these numbers I call UMax the biggest unsigned number 342 | Dialogue: 0,0:31:27.38,0:31:32.60,English,,0,0,0,,TMin the smallest most negative two's complement monitor and 343 | Dialogue: 0,0:31:32.60,0:31:36.42,English,,0,0,0,,TMax the largest most positive two's complement 344 | Dialogue: 0,0:31:36.76,0:31:42.46,English,,0,0,0,,This chart shows the range of values for different word sizes different numbers of bytes 345 | Dialogue: 0,0:31:43.02,0:31:51.16,English,,0,0,0,,And so you'll see that with an 8 bit number you only have 256 possibilities right 346 | Dialogue: 0,0:31:54.66,0:32:01.68,English,,0,0,0,, And so we can either choose to rate think of those as representing the range from 0 to 255 347 | Dialogue: 0,0:32:01.86,0:32:07.52,English,,0,0,0,, Or basically with two's complement numbers we're just doing a sort of a wraparound we're saying 348 | Dialogue: 0,0:32:07.52,0:32:13.24,English,,0,0,0,,Well we're going to have half of them be negative and the other half will be either 0 or positive 349 | Dialogue: 0,0:32:16.62,0:32:19.34,English,,0,0,0,,And so it's a pretty limited range of values of course 350 | Dialogue: 0,0:32:19.34,0:32:25.74,English,,0,0,0,,Then 16 and believe me back when computers had 16-bit word sizes 351 | Dialogue: 0,0:32:25.74,0:32:29.48,English,,0,0,0,, It was a nuisance to keep your numbers within that range 352 | Dialogue: 0,0:32:29.94,0:32:33.61,English,,0,0,0,, And 32 gives you a pretty decent range it used to be said 353 | Dialogue: 0,0:32:33.98,0:32:41.00,English,,0,0,0,,Microsoft had to go to 64-bit word size to represent Bill Gates's net worth but 354 | Dialogue: 0,0:32:43.90,0:32:49.66,English,,0,0,0,,For me at least this would easily handle my range of normal day-to-day transactions so 355 | Dialogue: 0,0:32:51.74,0:33:00.16,English,,0,0,0,, But now with 64 bits at least to us nowadays those seem like really big numbers and hard to imagine exceeding the bounds of those 356 | Dialogue: 0,0:33:04.88,0:33:11.68,English,,0,0,0,, So one interesting feature that you noticed here was I was um 357 | Dialogue: 0,0:33:15.82,0:33:17.96,English,,0,0,0,,like this case here 358 | Dialogue: 0,0:33:24.88,0:33:27.02,English,,0,0,0,,In this case here... 359 | Dialogue: 0,0:33:36.16,0:33:39.88,English,,0,0,0,,And then this case here of all ones 360 | Dialogue: 0,0:33:43.28,0:33:47.98,English,,0,0,0,,I was comparing it to this case here of all ones 361 | Dialogue: 0,0:33:49.40,0:33:54.24,English,,0,0,0,,So in other words in both these cases and it's a little hard to jump boards here 362 | Dialogue: 0,0:33:56.64,0:34:00.04,English,,0,0,0,,You're seeing that you have the same bit pattern in either case 363 | Dialogue: 0,0:34:01.12,0:34:06.56,English,,0,0,0,,But they the numeric they represent different numeric values because one is a two's complement case 364 | Dialogue: 0,0:34:07.80,0:34:10.06,English,,0,0,0,,And the other is an unsigned right 365 | Dialogue: 0,0:34:10.12,0:34:14.38,English,,0,0,0,,And you can actually see the relation between them is pretty simple 366 | Dialogue: 0,0:34:14.76,0:34:24.08,English,,0,0,0,, Because basically what we're doing is we're jumping between +16 and -16 between those 367 | Dialogue: 0,0:34:24.44,0:34:27.84,English,,0,0,0,,And so you'd expect it to change by 32 right 368 | Dialogue: 0,0:34:28.54,0:34:32.16,English,,0,0,0,,And you see that here that this is 31 here and -1 369 | Dialogue: 0,0:34:32.68,0:34:43.14,English,,0,0,0,,This is 22 and -10 so they're differ from each other by plus -32 ,2^4,two to the word size 370 | Dialogue: 0,0:34:43.60,0:34:48.80,English,,0,0,0,,and so we there's sort of a long derivation in the book and things here 371 | Dialogue: 0,0:34:48.80,0:34:53.60,English,,0,0,0,,But that connection is actually fairly important 372 | Dialogue: 0,0:34:54.06,0:34:56.90,English,,0,0,0,,Because when you jump back and forth 373 | Dialogue: 0,0:34:57.70,0:35:01.82,English,,0,0,0,, Between unsigned numbers and two's complement numbers in C 374 | Dialogue: 0,0:35:03.08,0:35:07.44,English,,0,0,0,,That's the jump that you get in other words 375 | Dialogue: 0,0:35:07.64,0:35:10.48,English,,0,0,0,,when of and so 376 | Dialogue: 0,0:35:12.50,0:35:18.12,English,,0,0,0,,You'll often find cases where what used to be a very large number 377 | Dialogue: 0,0:35:18.12,0:35:20.80,English,,0,0,0,,Because it was unsigned all of a sudden becomes a negative number 378 | Dialogue: 0,0:35:20.80,0:35:22.72,English,,0,0,0,,Because it's considered two's complement 379 | Dialogue: 0,0:35:24.00,0:35:26.96,English,,0,0,0,,So that's what this next part covers will say that 380 | Dialogue: 0,0:35:32.24,0:35:35.91,English,,0,0,0,,If we take a cart of 4 bit numbers and 381 | Dialogue: 0,0:35:36.14,0:35:43.36,English,,0,0,0,,We write out all the possible values is unsigned or as two's complement numbers 382 | Dialogue: 0,0:35:43.64,0:35:48.83,English,,0,0,0,,Then the ones where the low the higher bid is 0 will be the same in both cases 383 | Dialogue: 0,0:35:49.38,0:35:54.80,English,,0,0,0,,The ones where the higher order bit is a 1 in this case will differ by 16 2^4 384 | Dialogue: 0,0:35:56.70,0:36:02.88,English,,0,0,0,,And similarly you'll notice that these numbers there's a unique 385 | Dialogue: 0,0:36:03.16,0:36:07.56,English,,0,0,0,,It goes unique in both directions there's a for any given bit pattern 386 | Dialogue: 0,0:36:07.78,0:36:10.95,English,,0,0,0,,There's a unique number it represents and 387 | Dialogue: 0,0:36:11.32,0:36:16.36,English,,0,0,0,,And similarly for any number within the given range there's a unique bit pattern 388 | Dialogue: 0,0:36:17.02,0:36:22.68,English,,0,0,0,,So we can sort of jump between those two and say 389 | Dialogue: 0,0:36:23.88,0:36:29.84,English,,0,0,0,, I can make up a rule for converting between a two's complement number X 390 | Dialogue: 0,0:36:29.84,0:36:32.18,English,,0,0,0,, and an unsigned number UX 391 | Dialogue: 0,0:36:32.36,0:36:37.50,English,,0,0,0,,That basically says I'll use the same bits I'll just think of them as being different numbers 392 | Dialogue: 0,0:36:38.10,0:36:42.12,English,,0,0,0,, And so and you can go either way 393 | Dialogue: 0,0:36:42.42,0:36:53.10,English,,0,0,0,, So for example if we thought of this is a a two's complement representative representation 394 | Dialogue: 0,0:36:53.86,0:37:04.48,English,,0,0,0,, It's -1 this function I'm calling T2U goes from that number -1 to this number 31 395 | Dialogue: 0,0:37:06.12,0:37:11.90,English,,0,0,0,,Where in between the two I'm saying they both have the same bit pattern 396 | Dialogue: 0,0:37:16.88,0:37:23.42,English,,0,0,0,,And the reason why this rather function that would otherwise seem to have no particular use is important 397 | Dialogue: 0,0:37:23.50,0:37:30.66,English,,0,0,0,,Because that's basically what happens in C or actually in the program 398 | Dialogue: 0,0:37:30.94,0:37:35.52,English,,0,0,0,,On the computer itself has no clue whether a given bit pattern if it's something 399 | Dialogue: 0,0:37:35.52,0:37:41.80,English,,0,0,0,, You're thinking of as being a negative number or two's complement number it's just a bunch of bits to it 400 | Dialogue: 0,0:37:43.60,0:37:51.22,English,,0,0,0,,And similarly so we can go back and forth between a two's complement and unsigned keeping the bit patterns the same 401 | Dialogue: 0,0:37:54.72,0:38:01.32,English,,0,0,0,,And so I'll call that T2U when I go from signed to unsigned two's complement unsigned 402 | Dialogue: 0,0:38:01.60,0:38:04.94,English,,0,0,0,, And say well I'll call U2T if I go from unsigned to signed 403 | Dialogue: 0,0:38:07.36,0:38:13.44,English,,0,0,0,,And as I mentioned the difference for the the numbers where the high-order bit is a 1 404 | Dialogue: 0,0:38:13.68,0:38:18.28,English,,0,0,0,,will be by a factor 2^w where w is the word size of the word 405 | Dialogue: 0,0:38:22.16,0:38:24.66,English,,0,0,0,, And so this can be thought of as a function 406 | Dialogue: 0,0:38:27.28,0:38:28.48,English,,0,0,0,, Where 407 | Dialogue: 0,0:38:34.84,0:38:36.18,English,,0,0,0,,Let me just draw it up 408 | Dialogue: 0,0:38:47.48,0:38:51.98,English,,0,0,0,,Over here with my five of bit numbers 409 | Dialogue: 0,0:38:55.30,0:39:01.50,English,,0,0,0,,That is the number this is two's complement again so that was the number -16 410 | Dialogue: 0,0:39:02.72,0:39:06.18,English,,0,0,0,,And then there'll be some other negative numbers up to all ones 411 | Dialogue: 0,0:39:09.48,0:39:11.00,English,,0,0,0,,This is number negative one 412 | Dialogue: 0,0:39:11.60,0:39:18.78,English,,0,0,0,,Then I'll have zero and so forth and then all up to 413 | Dialogue: 0,0:39:23.26,0:39:29.06,English,,0,0,0,,Plus 15 414 | Dialogue: 0,0:39:30.82,0:39:32.96,English,,0,0,0,,Destroys,I got myself in trouble 415 | Dialogue: 0,0:39:37.00,0:39:41.34,English,,0,0,0,,Blackboard management is they didn't teach me this in school 416 | Dialogue: 0,0:39:44.42,0:39:50.18,English,,0,0,0,, So I'm gonna use two boards and ones here 417 | Dialogue: 0,0:40:02.29,0:40:15.58,English,,0,0,0,,Okay let me send this out,okay we'll make it work 418 | Dialogue: 0,0:40:16.52,0:40:21.84,English,,0,0,0,,So now when we go from the T2U function then 419 | Dialogue: 0,0:40:22.64,0:40:25.10,English,,0,0,0,,These numbers are going to just carry over 420 | Dialogue: 0,0:40:25.50,0:40:30.18,English,,0,0,0,, We'll get 0 up through 15 421 | Dialogue: 0,0:40:32.46,0:40:36.84,English,,0,0,0,, But now this number here will become positive 16 422 | Dialogue: 0,0:40:41.70,0:40:51.02,English,,0,0,0,,And all ones will become positive 31 right 423 | Dialogue: 0,0:40:51.34,0:40:56.46,English,,0,0,0,,And so that's what this picture is showing is it for the pink numbers 424 | Dialogue: 0,0:40:57.50,0:41:03.25,English,,0,0,0,,are the ones that flip between negative and actually the largest of the positive numbers 425 | Dialogue: 0,0:41:03.92,0:41:08.68,English,,0,0,0,,And then the green numbers are the ones that stay the same because they're leading bits or zeros 426 | Dialogue: 0,0:41:14.82,0:41:16.26,English,,0,0,0,, So why does this matter bits or zeros 427 | Dialogue: 0,0:41:16.56,0:41:23.04,English,,0,0,0,,You never thought if you programmed in Python or even Java 428 | Dialogue: 0,0:41:23.30,0:41:33.32,English,,0,0,0,, You don't see that and the reason is because C is one of the few languages where unsigned is actually an explicit datatype 429 | Dialogue: 0,0:41:34.32,0:41:37.94,English,,0,0,0,,So you can declare a value being unsigned 430 | Dialogue: 0,0:41:38.34,0:41:42.52,English,,0,0,0,,And it's you can if you just say unsigned what you're really saying is unsigned int 431 | Dialogue: 0,0:41:43.32,0:41:48.46,English,,0,0,0,,Or you can call something an unsigned care and unsigned short or an unsigned long 432 | Dialogue: 0,0:41:49.78,0:41:56.68,English,,0,0,0,,So and you're declaring and see that it should think about using this representation we show on the right 433 | Dialogue: 0,0:41:56.98,0:41:59.72,English,,0,0,0,,When it's working on those numbers 434 | Dialogue: 0,0:42:01.82,0:42:08.28,English,,0,0,0,,So that's sort of one thing and this it's one thing if you declare a number and use it that way 435 | Dialogue: 0,0:42:08.28,0:42:17.30,English,,0,0,0,,But what gets people and the often got you is if you declare something if you have a in this case 436 | Dialogue: 0,0:42:17.72,0:42:21.34,English,,0,0,0,,Something that's declared as a two's complement number X to TX 437 | Dialogue: 0,0:42:22.00,0:42:26.34,English,,0,0,0,,And you assign it a value you at Y X it'll do an implicit casting 438 | Dialogue: 0,0:42:26.84,0:42:32.18,English,,0,0,0,, Which is exactly based on this conversion that we've been talking about and vice versa 439 | Dialogue: 0,0:42:34.32,0:42:41.86,English,,0,0,0,, And so as this example goes through this goes through some examples that 440 | Dialogue: 0,0:42:42.24,0:42:49.06,English,,0,0,0,,If I look at two numbers and I compare them or I actually I do any operation on them 441 | Dialogue: 0,0:42:49.06,0:42:56.18,English,,0,0,0,, I add them divide them anything implicitly it will try to make these to be of the same type 442 | Dialogue: 0,0:42:56.72,0:43:00.68,English,,0,0,0,,And the way it will do that is to say if both of them are signed 443 | Dialogue: 0,0:43:01.00,0:43:05.34,English,,0,0,0,, Then I'll do I'll treat them as a signed case 444 | Dialogue: 0,0:43:05.60,0:43:07.88,English,,0,0,0,,If either of them is unsigned 445 | Dialogue: 0,0:43:08.24,0:43:12.78,English,,0,0,0,,Then I'll convert the other one to be an unsigned number and do the operation 446 | Dialogue: 0,0:43:13.20,0:43:16.86,English,,0,0,0,, And so in particular this set of examples is imagine 447 | Dialogue: 0,0:43:16.86,0:43:21.73,English,,0,0,0,, I'm comparing these I'm saying these numbers are either equal less or greater 448 | Dialogue: 0,0:43:22.14,0:43:27.66,English,,0,0,0,,What will the outcomes be and the key to answering that question is to first of all figure out 449 | Dialogue: 0,0:43:28.20,0:43:32.52,English,,0,0,0,, Okay is it a signed or an unsigned comparison should I convert 450 | Dialogue: 0,0:43:33.40,0:43:39.80,English,,0,0,0,, One of these numbers to either of these numbers to an unsigned form before I do it 451 | Dialogue: 0,0:43:40.38,0:43:44.38,English,,0,0,0,,And the rule was if either argument is unsigned then you got to do it 452 | Dialogue: 0,0:43:45.30,0:43:53.80,English,,0,0,0,,And as you see when you put a u at the end either a u or U at the end of a numeric constant 453 | Dialogue: 0,0:43:54.20,0:43:56.70,English,,0,0,0,,You're saying this is an unsigned value 454 | Dialogue: 0,0:43:57.50,0:44:05.32,English,,0,0,0,, So for example if we compare a zero and zero unsigned they're equal 455 | Dialogue: 0,0:44:07.50,0:44:13.12,English,,0,0,0,,And if we combine negative one compare negative one to zero 456 | Dialogue: 0,0:44:13.72,0:44:17.20,English,,0,0,0,,We'll get that the first one is less 457 | Dialogue: 0,0:44:17.46,0:44:19.74,English,,0,0,0,,Because -1 is less than 0 458 | Dialogue: 0,0:44:20.40,0:44:25.22,English,,0,0,0,, But what would happen with the next one when we compare negative 1 to an unsigned 0 459 | Dialogue: 0,0:44:26.86,0:44:30.24,English,,0,0,0,,greater right 460 | Dialogue: 0,0:44:31.10,0:44:40.54,English,,0,0,0,,So this is the surprise and it has to do with...a number that I erased 461 | Dialogue: 0,0:44:44.38,0:44:47.64,English,,0,0,0,, but we can still get it remember this is negative one 462 | Dialogue: 0,0:44:49.84,0:44:54.20,English,,0,0,0,, But when I cast that to an unsigned number 463 | Dialogue: 0,0:44:54.71,0:45:03.84,English,,0,0,0,, I'm flipping this from -16 to +16 and turning this into 31 I'm turning it into actually the largest number I can represent 464 | Dialogue: 0,0:45:04.64,0:45:06.72,English,,0,0,0,,And so it will be greater than zero 465 | Dialogue: 0,0:45:07.80,0:45:15.42,English,,0,0,0,, So it's a little bit weird to think about I took an u0 which after all is to 0 and compared it to a negative 1 466 | Dialogue: 0,0:45:15.70,0:45:21.38,English,,0,0,0,,And it said oh you really meant 31 didn't you or whatever word size we're using 467 | Dialogue: 0,0:45:21.86,0:45:23.32,English,,0,0,0,, And so it said it's greater 468 | Dialogue: 0,0:45:25.14,0:45:29.04,English,,0,0,0,,And basically the rest of these you can answer in a similar way 469 | Dialogue: 0,0:45:32.76,0:45:39.02,English,,0,0,0,, That these two numbers are this is clearly one smaller than this 470 | Dialogue: 0,0:45:40.28,0:45:46.04,English,,0,0,0,,No I'm sorry this is a positive this is a negative number and 471 | Dialogue: 0,0:45:46.18,0:45:51.14,English,,0,0,0,,I compare those and the positive will be greater than the negative 472 | Dialogue: 0,0:45:51.86,0:45:55.68,English,,0,0,0,, I'll tell you in a minute why this number is written this way 473 | Dialogue: 0,0:45:56.82,0:45:59.78,English,,0,0,0,, The next one it's the same pair of numbers 474 | Dialogue: 0,0:46:01.30,0:46:02.54,English,,0,0,0,,But you see it's flipped 475 | Dialogue: 0,0:46:03.80,0:46:13.68,English,,0,0,0,,And the reason is this number on the left is TMax for 476 | Dialogue: 0,0:46:19.82,0:46:22.82,English,,0,0,0,,So it's the bit pattern in a 32-bit number 477 | Dialogue: 0,0:46:50.92,0:46:53.46,English,,0,0,0,,And to this day I have not memorized this number by the way 478 | Dialogue: 0,0:46:53.88,0:46:57.44,English,,0,0,0,,But and then this number is actually TMin 479 | Dialogue: 0,0:47:15.68,0:47:24.72,English,,0,0,0,,And that when I subtract you can think of it as this is negative TMax - 1 so that's TMin 480 | Dialogue: 0,0:47:25.14,0:47:29.30,English,,0,0,0,, So if I do an unsigned comparison between those two now think of those 481 | Dialogue: 0,0:47:29.58,0:47:36.72,English,,0,0,0,,This leading bit not being a negative weight But a positive weight you'll see that this is a bigger number than this one 482 | Dialogue: 0,0:47:41.96,0:47:48.42,English,,0,0,0,, And so it goes that -1 is greater than -2 if they're unsigned 483 | Dialogue: 0,0:47:49.40,0:47:56.71,English,,0,0,0,, Because -1 is you can think of it as converts into UMax it'll be the biggest number possible 484 | Dialogue: 0,0:47:57.06,0:48:05.84,English,,0,0,0,,And -2 will be would be 11110 485 | Dialogue: 0,0:48:17.98,0:48:20.44,English,,0,0,0,,So that can get fairly confusing 486 | Dialogue: 0,0:48:23.78,0:48:29.98,English,,0,0,0,,One final quirk this way of writing this number is there's a little side in the book about it 487 | Dialogue: 0,0:48:30.54,0:48:37.84,English,,0,0,0,, If you write a business number Oh as you'd expect - as - blah blah blah 648 488 | Dialogue: 0,0:48:40.60,0:48:47.70,English,,0,0,0,,It will actually get the C compiler gets kind of confused by that for obscure reasons 489 | Dialogue: 0,0:48:48.14,0:48:54.36,English,,0,0,0,, One other thing I should point out that it's a property that I don't think we cover well enough here 490 | Dialogue: 0,0:48:56.44,0:48:57.88,English,,0,0,0,,Let me see 491 | Dialogue: 0,0:49:02.64,0:49:06.50,English,,0,0,0,,There's a few things that the tides don't really cover here and I don't know why not 492 | Dialogue: 0,0:49:07.26,0:49:08.58,English,,0,0,0,,They like to point out 493 | Dialogue: 0,0:49:13.66,0:49:17.62,English,,0,0,0,,That are kind of useful properties to keep track of 494 | Dialogue: 0,0:49:25.38,0:49:32.84,English,,0,0,0,,It's that you notice that if you look at the absolute value of TMax 495 | Dialogue: 0,0:49:35.26,0:49:38.12,English,,0,0,0,,And you compare it to the absolute value of TMin 496 | Dialogue: 0,0:49:40.72,0:49:46.90,English,,0,0,0,,That it's off by one right 497 | Dialogue: 0,0:49:47.36,0:49:50.24,English,,0,0,0,,So that the negative number is more negative 498 | Dialogue: 0,0:49:50.24,0:49:55.42,English,,0,0,0,,The smallest negative number is more negative than the largest positive number is positive 499 | Dialogue: 0,0:49:56.24,0:49:59.44,English,,0,0,0,,And the reason for that actually is fairly simple if you think about 500 | Dialogue: 0,0:49:59.78,0:50:05.62,English,,0,0,0,, It is that the the cases where you have zeros 501 | Dialogue: 0,0:50:07.88,0:50:09.36,English,,0,0,0,,Include the number 0 502 | Dialogue: 0,0:50:21.24,0:50:22.56,English,,0,0,0,,So you can see it better 503 | Dialogue: 0,0:50:26.40,0:50:32.40,English,,0,0,0,,And there's two to the half-year range is occupied by those numbers 504 | Dialogue: 0,0:50:32.96,0:50:36.86,English,,0,0,0,, And the negative numbers are all negative 505 | Dialogue: 0,0:50:42.10,0:50:46.80,English,,0,0,0,,And there's so the other half of the range is in there 506 | Dialogue: 0,0:50:48.26,0:50:51.70,English,,0,0,0,,And the point is that you had to use one of these four zero 507 | Dialogue: 0,0:50:52.16,0:50:57.34,English,,0,0,0,,And so they're only there's one left one less value left over 508 | Dialogue: 0,0:50:57.72,0:51:01.82,English,,0,0,0,, And that's why you end up with this through a symmetry 509 | Dialogue: 0,0:51:02.50,0:51:06.92,English,,0,0,0,,And this a symmetry is the cause of no end of pain in various ways 510 | Dialogue: 0,0:51:07.72,0:51:15.62,English,,0,0,0,,That like a few the classic example is if you implement absolute value 511 | Dialogue: 0,0:51:33.40,0:51:39.96,English,,0,0,0,,Like so what do you what does this return for TMin 512 | Dialogue: 0,0:51:44.62,0:51:50.32,English,,0,0,0,,Yeah the returns team in we'll talk a little bit basically 513 | Dialogue: 0,0:51:51.84,0:51:56.04,English,,0,0,0,, When you try to negate this number that's here 514 | Dialogue: 0,0:51:59.14,0:52:00.84,English,,0,0,0,, You'll end up with it back again 515 | Dialogue: 0,0:52:08.06,0:52:12.92,English,,0,0,0,,So it's always a corner case and whenever we do program testing 516 | Dialogue: 0,0:52:12.92,0:52:16.24,English,,0,0,0,, We always throw that case in there to break things question 517 | Dialogue: 0,0:52:17.00,0:52:33.36,English,,0,0,0,, well that case you said oh yeah big number but how negative - one yes 518 | Dialogue: 0,0:52:33.36,0:52:40.00,English,,0,0,0,,No that's what they do that if you ever look at the in the C constance 519 | Dialogue: 0,0:52:40.00,0:52:42.70,English,,0,0,0,, They use this as a way of representing TMin 520 | Dialogue: 0,0:52:43.26,0:52:46.84,English,,0,0,0,, And they do it for that reason because you see 521 | Dialogue: 0,0:52:47.16,0:52:52.54,English,,0,0,0,,It's exactly this problem and they put parentheses around it so there's no president's problem 522 | Dialogue: 0,0:52:52.72,0:52:56.38,English,,0,0,0,, But you see that number that in six for seven that's TMax 523 | Dialogue: 0,0:52:57.74,0:53:04.36,English,,0,0,0,,And so basically it's just saying that TMin is -TMax - 1 524 | Dialogue: 0,0:53:04.72,0:53:05.64,English,,0,0,0,,Question 525 | Dialogue: 0,0:53:06.34,0:53:15.70,English,,0,0,0,,[student speaking] 526 | Dialogue: 0,0:53:17.46,0:53:20.06,English,,0,0,0,,yeah hmm yes 527 | Dialogue: 0,0:53:20.28,0:53:23.76,English,,0,0,0,,So comparison is just a special case of the more general one 528 | Dialogue: 0,0:53:24.00,0:53:28.16,English,,0,0,0,, Which is addition subtraction all of those 529 | Dialogue: 0,0:53:28.94,0:53:34.18,English,,0,0,0,,If either argument is unsigned then it interprets remaining one as being unsigned 530 | Dialogue: 0,0:53:35.24,0:53:39.92,English,,0,0,0,,It turns out and we'll get into this more next time as far as bit patterns but 531 | Dialogue: 0,0:53:40.00,0:53:48.56,English,,0,0,0,,But it turns out that at the bit level addition subtraction even multiplication 532 | Dialogue: 0,0:53:49.08,0:53:52.44,English,,0,0,0,, are the same whether it's an unsigned number two's complement number 533 | Dialogue: 0,0:53:52.84,0:53:55.28,English,,0,0,0,, So what we'll talk about that more next time 534 | Dialogue: 0,0:53:59.50,0:54:04.00,English,,0,0,0,, And the other thing to observe sort of property 535 | Dialogue: 0,0:54:17.36,0:54:31.56,English,,0,0,0,,is you saw that UMax is sort of like 2 * TMax + 1 right so 536 | Dialogue: 0,0:54:32.74,0:54:39.26,English,,0,0,0,,So before UMax was 15 in our five bit numbers 537 | Dialogue: 0,0:54:39.66,0:54:42.74,English,,0,0,0,,And and that's again not too hard to figure out 538 | Dialogue: 0,0:54:44.66,0:54:50.40,English,,0,0,0,,Here's one way to think about it ,TMax is a zero followed by a bunch of ones 539 | Dialogue: 0,0:54:53.18,0:54:55.36,English,,0,0,0,,And if I want to double that number position 540 | Dialogue: 0,0:54:55.88,0:55:00.32,English,,0,0,0,,I basically shift it left by one position 541 | Dialogue: 0,0:55:01.66,0:55:03.78,English,,0,0,0,, And that would end up with a zero here 542 | Dialogue: 0,0:55:04.96,0:55:10.96,English,,0,0,0,, So this is TMax and this is twice TMax 543 | Dialogue: 0,0:55:13.04,0:55:14.72,English,,0,0,0,,And now if I add a one to that 544 | Dialogue: 0,0:55:16.30,0:55:18.82,English,,0,0,0,,That I'll just set this bit to one and get this 545 | Dialogue: 0,0:55:18.82,0:55:22.72,English,,0,0,0,, So there's various ways you can think about it but that's one way to do it 546 | Dialogue: 0,0:55:40.34,0:55:46.36,English,,0,0,0,,It's one other thing that I wanted to mention too 547 | Dialogue: 0,0:55:47.20,0:55:57.58,English,,0,0,0,,This can get you into a lot of trouble programming wise so let me just show you what I mean 548 | Dialogue: 0,0:56:07.08,0:56:15.64,English,,0,0,0,,So I mentioned I wanted to go backwards through an array 549 | Dialogue: 0,0:56:16.06,0:56:22.78,English,,0,0,0,, So I write a loop of the form for i = n - 1 550 | Dialogue: 0,0:56:23.52,0:56:29.70,English,,0,0,0,,i >= 0 551 | Dialogue: 0,0:56:31.20,0:56:32.54,English,,0,0,0,,i-- 552 | Dialogue: 0,0:56:33.98,0:56:37.34,English,,0,0,0,,then I do something with array element a of i 553 | Dialogue: 0,0:56:40.56,0:56:42.60,English,,0,0,0,,I just call some function of 554 | Dialogue: 0,0:56:43.90,0:56:47.94,English,,0,0,0,,Whatever you want to do in that loop so that's a pretty standard pattern in a loop right 555 | Dialogue: 0,0:56:48.68,0:56:53.36,English,,0,0,0,, Except that you write this greater equal to1 0 556 | Dialogue: 0,0:56:54.56,0:56:56.84,English,,0,0,0,,You can imagine various uses for that 557 | Dialogue: 0,0:56:57.76,0:57:06.04,English,,0,0,0,,So here's an interesting question what if I were declared as being unsigned 558 | Dialogue: 0,0:57:09.16,0:57:12.66,English,,0,0,0,, Because it's array index after all what will happen with this loop 559 | Dialogue: 0,0:57:18.02,0:57:18.90,English,,0,0,0,,What's that? 560 | Dialogue: 0,0:57:20.46,0:57:24.22,English,,0,0,0,, Yes! So the loop will go forever what would most likely happen is 561 | Dialogue: 0,0:57:24.98,0:57:27.56,English,,0,0,0,,I would go from being zero to being UMax 562 | Dialogue: 0,0:57:28.66,0:57:31.00,English,,0,0,0,, And that's a really big number and 563 | Dialogue: 0,0:57:31.10,0:57:39.14,English,,0,0,0,,The ray,you'd uh, most likely cause a memory fault because it's so far out of bounds 564 | Dialogue: 0,0:57:39.72,0:57:43.86,English,,0,0,0,, But the point is it wouldn't do what you want it wouldn't stop where you want it to 565 | Dialogue: 0,0:57:44.42,0:57:47.58,English,,0,0,0,, Because of the simple reason that I is of course 566 | Dialogue: 0,0:57:48.52,0:57:52.66,English,,0,0,0,,i is always going to be greater than or equal to zero because it's an unsigned number 567 | Dialogue: 0,0:57:53.46,0:57:59.84,English,,0,0,0,,So that's one you'd say okay well you should have figured that one out 568 | Dialogue: 0,0:58:00.28,0:58:02.44,English,,0,0,0,,It can be fair it more subtle though 569 | Dialogue: 0,0:58:06.60,0:58:10.62,English,,0,0,0,, If you have something like int i 570 | Dialogue: 0,0:58:14.40,0:58:22.86,English,,0,0,0,, And then we say something like let me just change it here a little bit so this will be 571 | Dialogue: 0,0:58:40.70,0:58:46.18,English,,0,0,0,,Something like this where the I'm mixing metaphors here I have to confess 572 | Dialogue: 0,0:58:46.72,0:58:52.82,English,,0,0,0,,But if you use the standard the term size of which is the way you get 573 | Dialogue: 0,0:58:53.18,0:58:56.26,English,,0,0,0,, How many bytes it takes to represent some given data type 574 | Dialogue: 0,0:58:56.66,0:58:58.64,English,,0,0,0,,So this will actually be the number one 575 | Dialogue: 0,0:58:59.68,0:59:08.20,English,,0,0,0,,So it's not the same loop as before but imagine I'm sort of mixing in my arithmetic and making use of some of these built-in forms 576 | Dialogue: 0,0:59:10.08,0:59:11.80,English,,0,0,0,, What would happen with this loop 577 | Dialogue: 0,0:59:14.08,0:59:21.42,English,,0,0,0,, Yes right yes 578 | Dialogue: 0,0:59:21.76,0:59:26.92,English,,0,0,0,,Exactly so sizeof returns an unsigned value 579 | Dialogue: 0,0:59:26.92,0:59:32.76,English,,0,0,0,, It's not actually a function it's a built in but it's the result of sizeof is considered to be unsigned 580 | Dialogue: 0,0:59:33.48,0:59:37.32,English,,0,0,0,, And so just like I was saying 581 | Dialogue: 0,0:59:37.62,0:59:42.78,English,,0,0,0,,If you have a signed value in it unsigned in any kind of arithmetic 582 | Dialogue: 0,0:59:43.32,0:59:47.78,English,,0,0,0,, It'll turn treat the combination of the two is unsigned 583 | Dialogue: 0,0:59:48.14,0:59:51.30,English,,0,0,0,, And so it will actually do an unsigned comparison here 584 | Dialogue: 0,0:59:51.80,0:59:53.94,English,,0,0,0,, Which is almost surely not what you wanted 585 | Dialogue: 0,0:59:54.92,1:00:02.61,English,,0,0,0,,And this will just you'll look at this program and you won't have any idea why it's crashing 586 | Dialogue: 0,1:00:02.84,1:00:07.04,English,,0,0,0,,You'll be so confused and that's the kind of thing you have to know 587 | Dialogue: 0,1:00:07.04,1:00:11.80,English,,0,0,0,, It's one of the quirks of C that probably a fake could start over again and redesign it 588 | Dialogue: 0,1:00:11.80,1:00:14.84,English,,0,0,0,,They'd come up with some different set of conventions than they did 589 | Dialogue: 0,1:00:15.20,1:00:19.78,English,,0,0,0,,But unfortunately it's way too late for that so this is just one of those things you have to remember 590 | Dialogue: 0,1:00:21.18,1:00:25.54,English,,0,0,0,, But yes the my point is through some subtleties to spent about in signed 591 | Dialogue: 0,1:00:25.78,1:00:29.10,English,,0,0,0,,About this business of signed versus unsigned arithmetic 592 | Dialogue: 0,1:00:36.16,1:00:41.86,English,,0,0,0,,Okay so now let's look at a sort of final class of operations which is 593 | Dialogue: 0,1:00:42.46,1:00:46.42,English,,0,0,0,,Suppose I have a number that's so many bits say eight bits 594 | Dialogue: 0,1:00:46.48,1:00:51.02,English,,0,0,0,, And I want to now expand it to be a 16-bit number 595 | Dialogue: 0,1:00:51.60,1:00:54.70,English,,0,0,0,,There's a fairly cute rule for doing this 596 | Dialogue: 0,1:00:55.12,1:00:59.82,English,,0,0,0,,That's called sign extension I'm talking about two's complement numbers here 597 | Dialogue: 0,1:01:00.36,1:01:06.64,English,,0,0,0,, Of how you go take a and make it bigger without changing its value 598 | Dialogue: 0,1:01:08.48,1:01:14.96,English,,0,0,0,,And the basic rule is you do it by copying the sign bit to the left 599 | Dialogue: 0,1:01:15.42,1:01:18.12,English,,0,0,0,,So let me give you the intuition behind it 600 | Dialogue: 0,1:01:29.50,1:01:32.38,English,,0,0,0,,So let's go get some 4-bit values 601 | Dialogue: 0,1:01:42.10,1:01:45.54,English,,0,0,0,,Well it's pretty straightforward if the leading bit is a zero 602 | Dialogue: 0,1:01:46.84,1:01:52.32,English,,0,0,0,,I'm just going to do a left shift and then fill in so 603 | Dialogue: 0,1:01:59.54,1:02:00.80,English,,0,0,0,,Wait what am I talking about 604 | Dialogue: 0,1:02:04.80,1:02:07.10,English,,0,0,0,, I got ahead of myself I'm talking about something totally different 605 | Dialogue: 0,1:02:07.12,1:02:11.54,English,,0,0,0,, No sorry the same number I'm not changing the number I keeping it the same 606 | Dialogue: 0,1:02:11.54,1:02:19.48,English,,0,0,0,,So I just add a zero to the lead and this will be the number six still this is 4 + 2=6 607 | Dialogue: 0,1:02:21.94,1:02:25.88,English,,0,0,0,,But now let's think about it as a where there's a leading sign bit 608 | Dialogue: 0,1:02:29.12,1:02:36.24,English,,0,0,0,, So this is -8 + 4 + 2 = -2 609 | Dialogue: 0,1:02:38.08,1:02:45.24,English,,0,0,0,,So now look at what happens if I copy that sign bit over one position 610 | Dialogue: 0,1:02:48.18,1:02:56.34,English,,0,0,0,,so this becomes a 11110 611 | Dialogue: 0,1:02:57.64,1:03:02.42,English,,0,0,0,, And what happens is this is a now has value plus 8 here 612 | Dialogue: 0,1:03:02.72,1:03:05.56,English,,0,0,0,, But the sign bit has value -16 613 | Dialogue: 0,1:03:06.22,1:03:08.50,English,,0,0,0,,And then this is still +2 and +4 and 614 | Dialogue: 0,1:03:10.58,1:03:12.62,English,,0,0,0,,So it will still equal -2 615 | Dialogue: 0,1:03:14.02,1:03:20.58,English,,0,0,0,,So here's what happened before my sign bit had a weight of -8 616 | Dialogue: 0,1:03:21.80,1:03:24.76,English,,0,0,0,,My new sign bit has a weight of -16 617 | Dialogue: 0,1:03:25.72,1:03:29.90,English,,0,0,0,, But I converted that old sign bit into a positive number which is +8 618 | Dialogue: 0,1:03:30.64,1:03:34.20,English,,0,0,0,, And those 2 cancelled out sit right the duck 619 | Dialogue: 0,1:03:34.40,1:03:39.06,English,,0,0,0,, That you combine those two and you get a -8 which is exactly this 620 | Dialogue: 0,1:03:39.66,1:03:50.46,English,,0,0,0,, So you see by sort of copying that sign bit over giving it twice the weight turning it what was the sign bit into a positive number 621 | Dialogue: 0,1:03:50.80,1:03:53.92,English,,0,0,0,,You don't change the net effect of the sum 622 | Dialogue: 0,1:03:54.22,1:04:00.51,English,,0,0,0,,And that's exactly the idea of sign extension just keep going with that as far as you need to carry it over 623 | Dialogue: 0,1:04:00.86,1:04:08.22,English,,0,0,0,,And each time you're doing it you're effectively doing this business of coming up with a pair of bits 624 | Dialogue: 0,1:04:08.84,1:04:11.94,English,,0,0,0,,that end up with the same value as this original bit 625 | Dialogue: 0,1:04:13.70,1:04:20.88,English,,0,0,0,,So that's the idea of sign extension and you'll see that a lot in bit patterns 626 | Dialogue: 0,1:04:21.50,1:04:27.46,English,,0,0,0,, Especially if you see a bit pattern with it starts with a bunch of Fs 627 | Dialogue: 0,1:04:35.92,1:04:40.98,English,,0,0,0,,What that tells you remember F is just four ones 628 | Dialogue: 0,1:04:46.70,1:04:50.10,English,,0,0,0,, is a whole bunch of leading ones that tells you the number is negative 629 | Dialogue: 0,1:04:51.14,1:04:54.10,English,,0,0,0,, Negative but not too far away from zero right 630 | Dialogue: 0,1:04:54.76,1:04:58.74,English,,0,0,0,,And you'll see that over and over again you'll see bit patterns and you just sort of want it 631 | Dialogue: 0,1:04:58.94,1:05:03.24,English,,0,0,0,,When you see leading Fs you say oh that's a negative number I know what's going on there 632 | Dialogue: 0,1:05:07.56,1:05:13.76,English,,0,0,0,,And so here's some examples but like you can see the main idea is you carry that leading bit 633 | Dialogue: 0,1:05:14.56,1:05:20.32,English,,0,0,0,,from the 16-bit case over and make as many copies you need to expand the word size 634 | Dialogue: 0,1:05:24.73,1:05:31.60,English,,0,0,0,,And I should mention with the unsigned case obviously you just want to fill in with zeros 635 | Dialogue: 0,1:05:36.84,1:05:42.48,English,,0,0,0,,To talk about truncation and send missing slides in this but um 636 | Dialogue: 0,1:05:49.98,1:05:54.42,English,,0,0,0,,A final case to look at is what happens if I make something shorter 637 | Dialogue: 0,1:05:57.44,1:06:00.16,English,,0,0,0,,So if I had my unsigned number from before 638 | Dialogue: 0,1:06:07.18,1:06:10.74,English,,0,0,0,,If this were an unsigned number this would be 639 | Dialogue: 0,1:06:12.04,1:06:20.78,English,,0,0,0,,1 2 8 16 14 17 right 640 | Dialogue: 0,1:06:21.48,1:06:32.34,English,,0,0,0,,What if I decided oh I can't afford 4 bit I don't have enough money for 5 bits I'm only going to give you 4 641 | Dialogue: 0,1:06:33.74,1:06:36.40,English,,0,0,0,,Well you basically just drop the most significant bit 642 | Dialogue: 0,1:06:38.44,1:06:43.72,English,,0,0,0,,And you get 8 + 2 + 1 which is 11 643 | Dialogue: 0,1:06:44.20,1:06:53.32,English,,0,0,0,,Which is 9 and the relation there is that this is a it's like modular arithmetic 644 | Dialogue: 0,1:06:59.52,1:07:02.90,English,,0,0,0,,Right mod 16 you're taking...no 645 | Dialogue: 0,1:07:07.30,1:07:08.32,English,,0,0,0,,Thank you 646 | Dialogue: 0,1:07:12.62,1:07:23.58,English,,0,0,0,,It's the risk of improvising so 27 and 11 647 | Dialogue: 0,1:07:26.82,1:07:33.28,English,,0,0,0,,Yeah it makes sense,difference is 16 that I knew that 648 | Dialogue: 0,1:07:34.50,1:07:38.10,English,,0,0,0,, Okay excuse me for my stumbling 649 | Dialogue: 0,1:07:38.10,1:07:46.72,English,,0,0,0,, But the point being that when you drop this thing effectively you're just taking the mod some power of 2 of it like 650 | Dialogue: 0,1:07:47.10,1:07:49.72,English,,0,0,0,, I mentioned the case where you're taking module 8 651 | Dialogue: 0,1:07:50.02,1:07:54.10,English,,0,0,0,,If you just keep only the lowest order 3 bits you're having a module 8 652 | Dialogue: 0,1:07:54.52,1:07:58.78,English,,0,0,0,, Now one really this is a sort of logical in the unsigned world 653 | Dialogue: 0,1:07:59.24,1:08:04.78,English,,0,0,0,,Your modular arithmetic is something that was understood by the ancient Greeks 654 | Dialogue: 0,1:08:05.84,1:08:12.64,English,,0,0,0,,So not too far away from human experience 655 | Dialogue: 0,1:08:13.50,1:08:23.77,English,,0,0,0,,But it gets a little bit funky if you're dealing with two's complement numbers 656 | Dialogue: 0,1:08:24.38,1:08:33.26,English,,0,0,0,,Because this is now 10 11 -5 right 657 | Dialogue: 0,1:08:35.90,1:08:38.30,English,,0,0,0,,But this number if I just drop this bit and 658 | Dialogue: 0,1:08:39.96,1:08:44.90,English,,0,0,0,,And call it a 4-bit number this now becomes -8,2,1 659 | Dialogue: 0,1:08:50.48,1:08:51.56,English,,0,0,0,,It's -5 660 | Dialogue: 0,1:08:56.98,1:09:03.24,English,,0,0,0,,You say how'd that happen well actually if you look at it this is just what you'd get by sign extension right 661 | Dialogue: 0,1:09:05.04,1:09:07.74,English,,0,0,0,, So this wasn't a very interesting example 662 | Dialogue: 0,1:09:12.48,1:09:14.12,English,,0,0,0,, But if we changed it to this 663 | Dialogue: 0,1:09:22.88,1:09:27.32,English,,0,0,0,,Then this would be -13 664 | Dialogue: 0,1:09:28.06,1:09:30.46,English,,0,0,0,,And this would be +3 665 | Dialogue: 0,1:09:33.42,1:09:41.98,English,,0,0,0,,And it's a little harder to think about in terms of modular arithmetic 666 | Dialogue: 0,1:09:41.98,1:09:45.56,English,,0,0,0,, The way you basically have to think about it is well 667 | Dialogue: 0,1:09:46.40,1:09:56.94,English,,0,0,0,,You know this is -13 but it's really kind of like 27 and 27 mod 16 is sort of like or,no this isn't 20 668 | Dialogue: 0,1:09:57.24,1:10:05.70,English,,0,0,0,,We changed our number right so this is really kind of like 19.And 19 mod 16 is 3.And this is 3 669 | Dialogue: 0,1:10:05.82,1:10:10.86,English,,0,0,0,,So you can sort of do it by coming back around to it 670 | Dialogue: 0,1:10:10.86,1:10:16.82,English,,0,0,0,, But it's not sum of arithmetic property that would jump out at you as being something logical 671 | Dialogue: 0,1:10:17.72,1:10:21.82,English,,0,0,0,, But that happens all the time that and it's very common 672 | Dialogue: 0,1:10:22.18,1:10:25.64,English,,0,0,0,, For numbers to get truncated for one reason or another 673 | Dialogue: 0,1:10:25.68,1:10:29.74,English,,0,0,0,,And you can see that you can have a negative number become a positive number 674 | Dialogue: 0,1:10:30.06,1:10:32.48,English,,0,0,0,,You can have a positive number become a negative number 675 | Dialogue: 0,1:10:32.48,1:10:34.64,English,,0,0,0,,And all kinds of goofy stuff can happen 676 | Dialogue: 0,1:10:36.20,1:10:39.32,English,,0,0,0,,And we'll see plenty examples of that when we look at arithmetic 677 | Dialogue: 0,1:10:41.04,1:10:47.94,English,,0,0,0,,So that's,that is what I want to cover today 678 | Dialogue: 0,1:10:47.94,1:10:52.26,English,,0,0,0,,And we'll cover the other arithmetic operations on Tuesday 679 | Dialogue: 0,1:10:52.96,1:10:55.97,English,,0,0,0,,So thank you very much 680 | -------------------------------------------------------------------------------- /subtitle/English/Lecture 24 Synchronization Basics.ass: -------------------------------------------------------------------------------- 1 | [Script Info] 2 | ; Script generated by Aegisub r8942 3 | ; http://www.aegisub.org/ 4 | Title: Default Aegisub file 5 | ScriptType: v4.00+ 6 | WrapStyle: 0 7 | ScaledBorderAndShadow: yes 8 | YCbCr Matrix: TV.601 9 | PlayResX: 1280 10 | PlayResY: 720 11 | 12 | [Aegisub Project Garbage] 13 | Last Style Storage: Default 14 | Audio File: ../../../../Desktop/csapp/Lecture 24 Synchronization Basics.mp4 15 | Video File: ../../../../Desktop/csapp/Lecture 24 Synchronization Basics.mp4 16 | Video AR Mode: 4 17 | Video AR Value: 1.777778 18 | Video Zoom Percent: 1.000000 19 | Scroll Position: 635 20 | Active Line: 643 21 | Video Position: 101393 22 | 23 | [V4+ Styles] 24 | Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding 25 | Style: English,Source Han Sans CN,30,&H00FFFFFF,&H00412A2C,&H00412A2C,&H00412A2C,0,0,0,0,100,100,0,0,1,2.2,1,2,10,10,10,1 26 | Style: Chinese,Source Han Sans CN,34,&H00FBFD00,&H00FFFFFF,&H00362A28,&H00FFFFFF,0,0,0,0,100,100,0,0,1,2,0.2,2,10,10,10,1 27 | 28 | [Events] 29 | Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text 30 | Dialogue: 0,0:00:01.90,0:00:04.74,English,,0,0,0,,All right well good afternoon everybody good to see you welcome 31 | Dialogue: 0,0:00:06.54,0:00:09.10,English,,0,0,0,,Welcome to all those students watching on video as well 32 | Dialogue: 0,0:00:11.68,0:00:17.18,English,,0,0,0,,Before we start we were talking about joinable and detached threads 33 | Dialogue: 0,0:00:17.36,0:00:23.96,English,,0,0,0,,And you asked the question about why you would ever want to have threads running in non detached mode 34 | Dialogue: 0,0:00:24.00,0:00:27.12,English,,0,0,0,,You know why you'd ever run in want to have him running joinable 35 | Dialogue: 0,0:00:27.74,0:00:32.04,English,,0,0,0,,And I didn't give you a very good answer so I want to try to to answer that for you better 36 | Dialogue: 0,0:00:33.86,0:00:39.64,English,,0,0,0,,Turns out there's an important class of sort of parallel programming 37 | Dialogue: 0,0:00:40.02,0:00:43.60,English,,0,0,0,,There's an important parallel programming model called fork and join 38 | Dialogue: 0,0:00:44.38,0:00:47.84,English,,0,0,0,,Where program consists of a series of phases 39 | Dialogue: 0,0:00:50.56,0:00:56.56,English,,0,0,0,,In each phase you have a worker or a master sorry 40 | Dialogue: 0,0:00:57.66,0:01:00.54,English,,0,0,0,,And it creates a bunch of worker threads 41 | Dialogue: 0,0:01:05.90,0:01:10.12,English,,0,0,0,,And then each of those worker threads solve some part of the problem for that phase 42 | Dialogue: 0,0:01:10.48,0:01:15.02,English,,0,0,0,,Like some maybe you take your data structure and you break it up into chunks 43 | Dialogue: 0,0:01:15.04,0:01:19.82,English,,0,0,0,,And then each thread updates the its own chunk of that data structure 44 | Dialogue: 0,0:01:21.54,0:01:28.20,English,,0,0,0,,But for whatever reason the master then has to wait for the worker threads to finish before it can go on to the next phase 45 | Dialogue: 0,0:01:28.94,0:01:32.10,English,,0,0,0,,So it does join, so this is called the fork 46 | Dialogue: 0,0:01:33.26,0:01:35.60,English,,0,0,0,,And then it waits for all the threads to finish 47 | Dialogue: 0,0:01:37.32,0:01:40.00,English,,0,0,0,,By doing a join okay so this is called 48 | Dialogue: 0,0:01:41.20,0:01:43.50,English,,0,0,0,,This is called the fork and this is called the join 49 | Dialogue: 0,0:01:44.32,0:01:47.26,English,,0,0,0,,And only when all of the threads have finished 50 | Dialogue: 0,0:01:47.96,0:01:51.28,English,,0,0,0,,Can it go and do the next do the next phase 51 | Dialogue: 0,0:01:56.12,0:02:00.40,English,,0,0,0,,Okay so this model is really important in things like scientific computing where 52 | Dialogue: 0,0:02:01.22,0:02:06.76,English,,0,0,0,,You might...you're simulating some domain,you're simulating nature 53 | Dialogue: 0,0:02:07.40,0:02:10.76,English,,0,0,0,,So you represent that as some domain like maybe you're simulating 54 | Dialogue: 0,0:02:11.36,0:02:15.04,English,,0,0,0,,How heat flows over a plate you know metal plate 55 | Dialogue: 0,0:02:15.90,0:02:20.20,English,,0,0,0,,And so you might have these workers 56 | Dialogue: 0,0:02:21.30,0:02:24.04,English,,0,0,0,,You might partition the domain amongst a set of those workers 57 | Dialogue: 0,0:02:24.84,0:02:27.90,English,,0,0,0,,And then each one of these phases is a time step 58 | Dialogue: 0,0:02:28.94,0:02:34.24,English,,0,0,0,,And then so once all the workers have finished a time step then they can advance to the next time step 59 | Dialogue: 0,0:02:36.30,0:02:39.00,English,,0,0,0,,And so sorry I don't know why,I didn't think of it 60 | Dialogue: 0,0:02:39.52,0:02:41.76,English,,0,0,0,,That's a that's an important reason why you'd want this 61 | Dialogue: 0,0:02:44.04,0:02:45.16,English,,0,0,0,,Okay so we saw 62 | Dialogue: 0,0:02:46.36,0:02:50.30,English,,0,0,0,,We've seen the threaded programs are nice 63 | Dialogue: 0,0:02:50.30,0:02:53.04,English,,0,0,0,,Because you they you can share all the global variables 64 | Dialogue: 0,0:02:55.02,0:02:58.54,English,,0,0,0,,But this the sharing can have unintended consequences 65 | Dialogue: 0,0:02:59.36,0:03:02.98,English,,0,0,0,,So somehow we need a mechanism where we can control 66 | Dialogue: 0,0:03:02.98,0:03:07.08,English,,0,0,0,,How the flows of each individual thread are interleaved 67 | Dialogue: 0,0:03:08.28,0:03:12.52,English,,0,0,0,,So that bad things don't happen when we share data structures 68 | Dialogue: 0,0:03:12.78,0:03:17.74,English,,0,0,0,,Okay so this this process of controlling the interleaving is called synchronization 69 | Dialogue: 0,0:03:17.74,0:03:24.68,English,,0,0,0,,So we're going to look at techniques that you can use to write correct threaded programs by properly synchronizing them 70 | Dialogue: 0,0:03:27.28,0:03:29.56,English,,0,0,0,,Now first though we need to have a clear idea 71 | Dialogue: 0,0:03:30.10,0:03:34.78,English,,0,0,0,,So sharing is the issue right if we have threads that aren't sharing any resources 72 | Dialogue: 0,0:03:35.90,0:03:37.08,English,,0,0,0,,Then there's no problem right 73 | Dialogue: 0,0:03:37.16,0:03:42.02,English,,0,0,0,,That we saw this when we looked at it processes there's no shared data structures with processes 74 | Dialogue: 0,0:03:42.72,0:03:49.28,English,,0,0,0,,So we process these just run independently we don't really care how they're interleaved note no worries okay 75 | Dialogue: 0,0:03:49.80,0:03:54.14,English,,0,0,0,,But as soon as they introduce sharing then we have to be careful 76 | Dialogue: 0,0:03:56.24,0:04:00.58,English,,0,0,0,,Okay so to understand how to synchronize threads we first need to have a clear idea 77 | Dialogue: 0,0:04:01.02,0:04:05.20,English,,0,0,0,,Of what we mean by sharing in in threaded C programs 78 | Dialogue: 0,0:04:06.54,0:04:13.96,English,,0,0,0,,So the answer is not as simple as global variables are shared and stack variables are not shared 79 | Dialogue: 0,0:04:18.70,0:04:23.66,English,,0,0,0,,Okay so with instead what we x is shared 80 | Dialogue: 0,0:04:23.66,0:04:28.50,English,,0,0,0,,If only multiple threads reference some instance so that that variable x 81 | Dialogue: 0,0:04:29.51,0:04:34.00,English,,0,0,0,,All right so if only one thread is accessing a particular variable 82 | Dialogue: 0,0:04:35.64,0:04:37.06,English,,0,0,0,,Then it's not shared 83 | Dialogue: 0,0:04:38.26,0:04:38.76,English,,0,0,0,,Okay so... 84 | Dialogue: 0,0:04:40.32,0:04:45.24,English,,0,0,0,,In order to know exactly what we mean by shared we need to answer three questions 85 | Dialogue: 0,0:04:46.00,0:04:48.70,English,,0,0,0,,Okay first what is the memory model for threads 86 | Dialogue: 0,0:04:50.06,0:04:53.38,English,,0,0,0,,Okay second how are instances of variables mapped to memory 87 | Dialogue: 0,0:04:55.24,0:05:00.35,English,,0,0,0,,And then third how many threads might be referencing those the instances of those variables 88 | Dialogue: 0,0:05:00.64,0:05:03.84,English,,0,0,0,,Okay so we'll look at each of those now in turn each of those three questions 89 | Dialogue: 0,0:05:05.62,0:05:07.48,English,,0,0,0,,Okay so first is that the memory model 90 | Dialogue: 0,0:05:10.32,0:05:15.23,English,,0,0,0,,The conceptual model is a little bit different from the operational model the way it really works 91 | Dialogue: 0,0:05:15.56,0:05:16.78,English,,0,0,0,,Okay so conceptually 92 | Dialogue: 0,0:05:17.42,0:05:21.40,English,,0,0,0,,We have multiple threads that run in the context of a single process 93 | Dialogue: 0,0:05:22.38,0:05:26.90,English,,0,0,0,,Okay and some of that context is shared and some of its not shared 94 | Dialogue: 0,0:05:27.02,0:05:35.30,English,,0,0,0,,So each thread has its own separate thread id,stack,stack pointer,program counter,condition codes,general-purpose registers 95 | Dialogue: 0,0:05:36.60,0:05:43.78,English,,0,0,0,,And then they all share the remaining process context which is data structures that the kernel maintains 96 | Dialogue: 0,0:05:44.34,0:05:53.74,English,,0,0,0,,For the threads the virtual data structures to support the virtual memory system open files install signal handlers and so forth 97 | Dialogue: 0,0:05:55.24,0:05:59.24,English,,0,0,0,,So that's the conceptual model and that if that were really enforced 98 | Dialogue: 0,0:05:59.26,0:06:01.36,English,,0,0,0,,It would be nice it would make things simpler for us 99 | Dialogue: 0,0:06:01.42,0:06:05.60,English,,0,0,0,,But unfortunately in real life this model is not strictly enforced 100 | Dialogue: 0,0:06:07.30,0:06:13.00,English,,0,0,0,,Now although register values are really separate right the kernel maintains separate context for all the registers 101 | Dialogue: 0,0:06:13.02,0:06:14.42,English,,0,0,0,,So that part is good 102 | Dialogue: 0,0:06:15.72,0:06:21.64,English,,0,0,0,,But since the threads share the address space,a thread can access the the memory the stack 103 | Dialogue: 0,0:06:21.90,0:06:24.86,English,,0,0,0,,One thread can access the stack of an another thread 104 | Dialogue: 0,0:06:25.18,0:06:32.76,English,,0,0,0,,Okay so although conceptually these stacks are separate and distinct and in private they're really not 105 | Dialogue: 0,0:06:36.56,0:06:38.18,English,,0,0,0,,And so this can create some problems 106 | Dialogue: 0,0:06:38.18,0:06:42.28,English,,0,0,0,,So here's an example of that we'll come back to later 107 | Dialogue: 0,0:06:42.96,0:06:47.88,English,,0,0,0,,Of how this one thread can access the stack of another thread 108 | Dialogue: 0,0:06:48.54,0:06:51.54,English,,0,0,0,,So here we're defining a global variable called pointer 109 | Dialogue: 0,0:06:52.62,0:06:54.10,English,,0,0,0,,Which is a char ** 110 | Dialogue: 0,0:06:55.26,0:07:01.62,English,,0,0,0,,And then in the main routine on were declaring a local variable called messages which contains 111 | Dialogue: 0,0:07:02.32,0:07:05.30,English,,0,0,0,,It's a two element array which contains a couple strings 112 | Dialogue: 0,0:07:07.20,0:07:11.18,English,,0,0,0,,Which these will be printed out by the threads that we're going to create 113 | Dialogue: 0,0:07:12.22,0:07:17.28,English,,0,0,0,,And then we assign the global pointer to the address of the array messages 114 | Dialogue: 0,0:07:17.92,0:07:21.16,English,,0,0,0,,Okay so now pointer points to messages 115 | Dialogue: 0,0:07:22.66,0:07:25.56,English,,0,0,0,,And then we create in a loop we create two threads 116 | Dialogue: 0,0:07:27.66,0:07:30.76,English,,0,0,0,,Each of which executes this routine called thread 117 | Dialogue: 0,0:07:31.64,0:07:34.24,English,,0,0,0,,And and we're passing an argument 118 | Dialogue: 0,0:07:35.00,0:07:41.94,English,,0,0,0,,So the Pthreads will assign a thread id but in this case we're going to assign our own local thread id 119 | Dialogue: 0,0:07:42.16,0:07:43.58,English,,0,0,0,,By passing this loop index 120 | Dialogue: 0,0:07:44.32,0:07:47.66,English,,0,0,0,,Okay so this is an example we talked about this last time 121 | Dialogue: 0,0:07:49.24,0:07:51.76,English,,0,0,0,,It's kind of...it's this is perfectly okay there's no race 122 | Dialogue: 0,0:07:52.38,0:07:58.82,English,,0,0,0,,But it's a little weird because we're going to take this index i and cast it to a generic pointer 123 | Dialogue: 0,0:08:03.22,0:08:07.02,English,,0,0,0,,Okay and then after we create these threads then we'll exit the main thread 124 | Dialogue: 0,0:08:09.44,0:08:17.08,English,,0,0,0,,Now each the thread routine dereferences its argument to get the local the local thread id 125 | Dialogue: 0,0:08:17.96,0:08:21.40,English,,0,0,0,,And then it declares a static variable count 126 | Dialogue: 0,0:08:21.42,0:08:25.68,English,,0,0,0,,That we're going to use to count how many times this thread routine is called inside of a thread 127 | Dialogue: 0,0:08:27.38,0:08:33.66,English,,0,0,0,,And then it just prints a simple message from identifying that giving the local thread id 128 | Dialogue: 0,0:08:35.04,0:08:40.42,English,,0,0,0,,And then the message indexed by myid 129 | Dialogue: 0,0:08:40.90,0:08:42.90,English,,0,0,0,,So pointer points to messages 130 | Dialogue: 0,0:08:43.00,0:08:46.40,English,,0,0,0,,So thread zero will print "hello from foo" 131 | Dialogue: 0,0:08:47.32,0:08:50.44,English,,0,0,0,,And thread 1 will print "hello from bar" 132 | Dialogue: 0,0:08:51.86,0:08:55.92,English,,0,0,0,,And then we increment the pre increment the counter variable 133 | Dialogue: 0,0:08:58.80,0:08:59.46,English,,0,0,0,,Okay so 134 | Dialogue: 0,0:09:02.36,0:09:07.62,English,,0,0,0,,Although it doesn't you would it looks like we're accessing this global variable pointer 135 | Dialogue: 0,0:09:08.02,0:09:14.46,English,,0,0,0,,But since that was assigned to be the address of the local variable on the main thread stack 136 | Dialogue: 0,0:09:15.10,0:09:23.26,English,,0,0,0,,We've got this these peer threads accessing local variables on the main thread stack okay 137 | Dialogue: 0,0:09:23.36,0:09:28.22,English,,0,0,0,,So that I just this is not it you never want to do this as a very bad practice 138 | Dialogue: 0,0:09:28.22,0:09:30.96,English,,0,0,0,,But I...it's a kind of thing that can happen sometimes 139 | Dialogue: 0,0:09:33.84,0:09:39.28,English,,0,0,0,,By accident you know if you forget that pointer actually was assigned to you know some stack address 140 | Dialogue: 0,0:09:41.08,0:09:46.60,English,,0,0,0,,Okay so the second question that is how do we map variable instances to memory 141 | Dialogue: 0,0:09:47.10,0:09:50.16,English,,0,0,0,,Now we looked at this when we studied linking 142 | Dialogue: 0,0:09:50.16,0:09:54.78,English,,0,0,0,,But let's just review this quickly again to make sure that it's clear to you 143 | Dialogue: 0,0:09:56.80,0:10:01.38,English,,0,0,0,,So global variables are variables that are referenced outside of a function 144 | Dialogue: 0,0:10:03.00,0:10:08.08,English,,0,0,0,,And virtual memory the linker when it does symbol resolution make sure that 145 | Dialogue: 0,0:10:08.08,0:10:12.50,English,,0,0,0,,There's exactly one instance of every global variable in virtual memory 146 | Dialogue: 0,0:10:16.50,0:10:20.14,English,,0,0,0,,Now local variables are declared on the stack inside of a function 147 | Dialogue: 0,0:10:23.26,0:10:24.94,English,,0,0,0,,Without the static attribute 148 | Dialogue: 0,0:10:26.28,0:10:32.46,English,,0,0,0,,And so in this case each the stack for each thread will contain one instance of that local variable 149 | Dialogue: 0,0:10:37.60,0:10:37.94,English,,0,0,0,,Now 150 | Dialogue: 0,0:10:39.30,0:10:42.70,English,,0,0,0,,If variables are declared inside of a function with the static attribute 151 | Dialogue: 0,0:10:44.28,0:10:49.06,English,,0,0,0,,Then the scope of that variable is limited to that function meaning no other function can access it 152 | Dialogue: 0,0:10:50.56,0:10:55.66,English,,0,0,0,,But that static variable is stored along with all the other local variables 153 | Dialogue: 0,0:10:55.70,0:11:04.14,English,,0,0,0,,So there's any static variable declared inside of a function has exactly one instance in memory 154 | Dialogue: 0,0:11:04.96,0:11:10.66,English,,0,0,0,,And if you were to have say multiple functions that declared (the same) a static variable with the same name 155 | Dialogue: 0,0:11:11.30,0:11:14.44,English,,0,0,0,,The compiler would disambiguate those somehow 156 | Dialogue: 0,0:11:14.44,0:11:17.24,English,,0,0,0,,It would append some kind of unique 157 | Dialogue: 0,0:11:19.10,0:11:20.80,English,,0,0,0,,It would somehow make that name unique 158 | Dialogue: 0,0:11:24.48,0:11:30.14,English,,0,0,0,,Okay so what recall how all these different types of variable instances are mapped into memory 159 | Dialogue: 0,0:11:31.86,0:11:35.38,English,,0,0,0,,Okay pointer is a global variable 160 | Dialogue: 0,0:11:35.38,0:11:40.16,English,,0,0,0,,So there's one instance of pointer in the address space 161 | Dialogue: 0,0:11:42.72,0:11:45.56,English,,0,0,0,,And it's stored in the data segment 162 | Dialogue: 0,0:11:50.54,0:11:57.40,English,,0,0,0,,i and messages are examples of local variables to main 163 | Dialogue: 0,0:11:58.44,0:12:05.12,English,,0,0,0,,So there's one instance of these stored on the stack of main stack 164 | Dialogue: 0,0:12:06.22,0:12:12.08,English,,0,0,0,,And we'll denote those with this notation we'll say variable i 165 | Dialogue: 0,0:12:12.70,0:12:17.04,English,,0,0,0,,i.m means variable i is stored on main stack 166 | Dialogue: 0,0:12:18.32,0:12:20.78,English,,0,0,0,,And messages is stored on the stack of main 167 | Dialogue: 0,0:12:23.52,0:12:28.86,English,,0,0,0,,Okay now myid is a local variable defined in this thread routine 168 | Dialogue: 0,0:12:30.34,0:12:32.48,English,,0,0,0,,And so there's actually since there's two of these threads 169 | Dialogue: 0,0:12:32.74,0:12:39.62,English,,0,0,0,,There's there's now there are in memory there's there's two instances of myid one for each stack 170 | Dialogue: 0,0:12:40.54,0:12:43.38,English,,0,0,0,,Okay associated with the stack associated with each thread 171 | Dialogue: 0,0:12:45.28,0:12:49.52,English,,0,0,0,,So myid.p0 is stored on peer thread 0's stack 172 | Dialogue: 0,0:12:50.26,0:12:54.64,English,,0,0,0,,And myid.p1 is stored on peer thread 1's stack 173 | Dialogue: 0,0:12:59.20,0:13:07.68,English,,0,0,0,,Ok and now this counter variable the static counter variable has just exactly one instance in virtual memory 174 | Dialogue: 0,0:13:07.98,0:13:13.02,English,,0,0,0,,And it sits in the data segment along with the other global variables like like pointer 175 | Dialogue: 0,0:13:17.34,0:13:18.62,English,,0,0,0,,Okay now so the question is 176 | Dialogue: 0,0:13:20.78,0:13:23.24,English,,0,0,0,,Which of these variables are shared and which are not 177 | Dialogue: 0,0:13:25.66,0:13:26.32,English,,0,0,0,,Okay so we can 178 | Dialogue: 0,0:13:28.50,0:13:36.88,English,,0,0,0,,Remember what we said is it's shared if more than one thread is accessing an instance of that variable 179 | Dialogue: 0,0:13:38.98,0:13:42.82,English,,0,0,0,,Okay so let's just list all the different variables 180 | Dialogue: 0,0:13:44.20,0:13:48.62,English,,0,0,0,,And then let's look at each of these threads and see if it's referenced by that thread 181 | Dialogue: 0,0:13:50.26,0:13:52.66,English,,0,0,0,,Okay so what about,what about pointer 182 | Dialogue: 0,0:13:54.80,0:13:59.45,English,,0,0,0,,Right there's just it's referenced by the main thread right 183 | Dialogue: 0,0:14:00.80,0:14:02.80,English,,0,0,0,,And what about peer threads zero 184 | Dialogue: 0,0:14:07.38,0:14:10.20,English,,0,0,0,,Yeah it's referenced by peer thread zero right here 185 | Dialogue: 0,0:14:12.88,0:14:14.14,English,,0,0,0,,Right here 186 | Dialogue: 0,0:14:15.80,0:14:17.56,English,,0,0,0,,And similarly for peer thread one 187 | Dialogue: 0,0:14:18.64,0:14:21.72,English,,0,0,0,,Okay so pointer is referenced by all three threads 188 | Dialogue: 0,0:14:25.02,0:14:25.90,English,,0,0,0,,Now what about count 189 | Dialogue: 0,0:14:29.32,0:14:31.78,English,,0,0,0,,Counts not referenced by the main thread 190 | Dialogue: 0,0:14:32.96,0:14:36.00,English,,0,0,0,,But it is referenced by the two peer threads 191 | Dialogue: 0,0:14:38.44,0:14:40.16,English,,0,0,0,,Now what about i in main 192 | Dialogue: 0,0:14:42.62,0:14:44.28,English,,0,0,0,,That's referenced by main of course 193 | Dialogue: 0,0:14:44.30,0:14:49.04,English,,0,0,0,,But not by but not by either of the two threads 194 | Dialogue: 0,0:14:50.74,0:14:52.84,English,,0,0,0,,Now we're about messages, the messages array 195 | Dialogue: 0,0:14:54.62,0:14:57.92,English,,0,0,0,,Okay so that's accessed by main 196 | Dialogue: 0,0:14:58.74,0:15:00.92,English,,0,0,0,,And indirectly through pointer 197 | Dialogue: 0,0:15:01.52,0:15:05.56,English,,0,0,0,,It's referenced by each of these two peer threads 198 | Dialogue: 0,0:15:07.66,0:15:12.24,English,,0,0,0,,Now what about myid defined in peer thread zero 199 | Dialogue: 0,0:15:14.20,0:15:16.54,English,,0,0,0,,Okay so that's referenced that's a local variable 200 | Dialogue: 0,0:15:16.54,0:15:21.06,English,,0,0,0,,So it's only referenced by peer thread zero right it's not referenced by either the other threads 201 | Dialogue: 0,0:15:21.08,0:15:29.00,English,,0,0,0,,And similarly for myid and in peer threat one 202 | Dialogue: 0,0:15:33.12,0:15:36.32,English,,0,0,0,,Okay so given that definition then 203 | Dialogue: 0,0:15:37.60,0:15:39.90,English,,0,0,0,,Which of these variables is shared 204 | Dialogue: 0,0:15:42.28,0:15:44.74,English,,0,0,0,,So it's really straightforward with yeah 205 | Dialogue: 0,0:15:50.56,0:15:55.88,English,,0,0,0,,Okay so the question is discount count as a share variable and answer is yes 206 | Dialogue: 0,0:15:56.70,0:15:59.10,English,,0,0,0,,Because it's declared static 207 | Dialogue: 0,0:15:59.86,0:16:03.66,English,,0,0,0,,It's there's one instance of it in virtual memory 208 | Dialogue: 0,0:16:04.94,0:16:08.82,English,,0,0,0,,And each of the threads references that instance 209 | Dialogue: 0,0:16:09.40,0:16:13.12,English,,0,0,0,,Okay so it's shared,it's really like a global variable 210 | Dialogue: 0,0:16:13.76,0:16:16.86,English,,0,0,0,,It's just a scope is limited to the... 211 | Dialogue: 0,0:16:18.30,0:16:22.98,English,,0,0,0,,It stored the same way a global variable is but its scope is limited to the function that it's defined in 212 | Dialogue: 0,0:16:24.48,0:16:27.26,English,,0,0,0,,Okay so to determine if each one of these is whether 213 | Dialogue: 0,0:16:27.48,0:16:30.14,English,,0,0,0,,Which of these variables are shared in which one's not we just 214 | Dialogue: 0,0:16:30.66,0:16:39.00,English,,0,0,0,,We just look go across and for any variable with its shared by more than,more than one thread then it's shared 215 | Dialogue: 0,0:16:39.68,0:16:40.78,English,,0,0,0,,So pointer shared 216 | Dialogue: 0,0:16:44.98,0:16:48.38,English,,0,0,0,,So pointer is shared count is not shared 217 | Dialogue: 0,0:16:50.92,0:16:56.10,English,,0,0,0,,Oh no count is shared because it's it's referenced by peer thread zero and peer thread one 218 | Dialogue: 0,0:16:58.42,0:17:01.62,English,,0,0,0,,I's not shared because it's only referenced by main 219 | Dialogue: 0,0:17:02.98,0:17:03.38,English,,0,0,0,,So 220 | Dialogue: 0,0:17:07.94,0:17:11.76,English,,0,0,0,,Messages is access referenced by all three threads so it's shared 221 | Dialogue: 0,0:17:12.78,0:17:18.60,English,,0,0,0,,But myid is not shared because it's only referenced by exactly one thread 222 | Dialogue: 0,0:17:19.02,0:17:28.22,English,,0,0,0,,Okay so pointer count and messages are the shared variables in this program and the others are run share 223 | Dialogue: 0,0:17:28.66,0:17:28.86,English,,0,0,0,,Yes 224 | Dialogue: 0,0:17:29.32,0:17:35.74,English,,0,0,0,,[student speaking] 225 | Dialogue: 0,0:17:35.74,0:17:37.86,English,,0,0,0,,So declared my ideas static 226 | Dialogue: 0,0:17:38.82,0:17:41.92,English,,0,0,0,,With the second process of overridden it yeah that would be a race 227 | Dialogue: 0,0:17:43.44,0:17:47.44,English,,0,0,0,,Okay so that would...we just depend on which thread executed first 228 | Dialogue: 0,0:17:48.16,0:17:50.32,English,,0,0,0,,So you would really wouldn't want to do that 229 | Dialogue: 0,0:17:55.38,0:18:00.26,English,,0,0,0,,Okay so we have a very clear notion now of what we mean by sharing 230 | Dialogue: 0,0:18:08.32,0:18:12.64,English,,0,0,0,,So these being able to share variables like this in this ways is very handy 231 | Dialogue: 0,0:18:14.12,0:18:16.54,English,,0,0,0,,But you can run into some really nasty problems 232 | Dialogue: 0,0:18:17.76,0:18:20.88,English,,0,0,0,,That are very surprising,so let me show you an example 233 | Dialogue: 0,0:18:23.28,0:18:24.34,English,,0,0,0,,This is a program 234 | Dialogue: 0,0:18:25.72,0:18:29.72,English,,0,0,0,,Called bad count so obviously there's something wrong with this I'm giving you a little clue 235 | Dialogue: 0,0:18:31.28,0:18:39.58,English,,0,0,0,,But what we want to do is we want to create a bunch of threads or a number of threads 236 | Dialogue: 0,0:18:40.46,0:18:44.18,English,,0,0,0,,And each of those threads will increment a global variable called count 237 | Dialogue: 0,0:18:45.00,0:18:47.04,English,,0,0,0,,Some number of times the same number of times 238 | Dialogue: 0,0:18:49.26,0:18:55.02,English,,0,0,0,,Okay so we pass in the number of iterations as the first argument 239 | Dialogue: 0,0:18:56.16,0:18:59.54,English,,0,0,0,,And here's our well here's our global globally shared variable 240 | Dialogue: 0,0:19:02.02,0:19:03.84,English,,0,0,0,,And you remember what volatile means 241 | Dialogue: 0,0:19:04.92,0:19:06.10,English,,0,0,0,,Everybody remember what that means 242 | Dialogue: 0,0:19:07.68,0:19:10.30,English,,0,0,0,,So what is volatile,what is volatile tell the compiler 243 | Dialogue: 0,0:19:10.98,0:19:11.48,English,,0,0,0,,Yes 244 | Dialogue: 0,0:19:11.60,0:19:22.66,English,,0,0,0,,[student speaking] 245 | Dialogue: 0,0:19:24.72,0:19:32.92,English,,0,0,0,,It actually you're on in the right direction actually tells,it tells the compiler never to put that variable in a register 246 | Dialogue: 0,0:19:33.72,0:19:38.96,English,,0,0,0,,Okay so it always read that value from memory or store it to memory and 247 | Dialogue: 0,0:19:39.54,0:19:44.64,English,,0,0,0,,You do that because of exactly the kind of possibility that you mentioned 248 | Dialogue: 0,0:19:46.90,0:19:50.60,English,,0,0,0,,So in this case we have 249 | Dialogue: 0,0:19:50.98,0:19:55.88,English,,0,0,0,,We create two threads by with two distinct calls to two pthread create 250 | Dialogue: 0,0:19:57.42,0:20:02.76,English,,0,0,0,,Each of these threads will run the the thread routine called thread 251 | Dialogue: 0,0:20:03.36,0:20:08.50,English,,0,0,0,,And it will pass and as an argument the address of the number of iterations that it should 252 | Dialogue: 0,0:20:09.34,0:20:10.18,English,,0,0,0,,That it should iterate 253 | Dialogue: 0,0:20:11.66,0:20:15.56,English,,0,0,0,,Now you remember when we were looking when we were passing connected file descriptors 254 | Dialogue: 0,0:20:16.76,0:20:18.70,English,,0,0,0,,If we pass an address that was a race 255 | Dialogue: 0,0:20:20.10,0:20:22.86,English,,0,0,0,,Okay but in this case there's no race this is fine 256 | Dialogue: 0,0:20:22.86,0:20:25.88,English,,0,0,0,,It's fine just to pass the address of number of iterations 257 | Dialogue: 0,0:20:26.46,0:20:32.52,English,,0,0,0,,So why is it okay in this case but it wasn't okay when we were passing the connected file descriptor 258 | Dialogue: 0,0:20:32.88,0:20:35.28,English,,0,0,0,,That we got from acceptant to our thread routine 259 | Dialogue: 0,0:20:49.06,0:20:51.98,English,,0,0,0,,Yes 260 | Dialogue: 0,0:20:52.00,0:20:54.40,English,,0,0,0,,Exactly because the thread doesn't modify the value 261 | Dialogue: 0,0:20:54.60,0:21:01.82,English,,0,0,0,,And that the problem we had before was that our main thread was modifying that connected descriptor on the next call to accept 262 | Dialogue: 0,0:21:02.56,0:21:04.76,English,,0,0,0,,But here it's just a read-only variable so we're okay 263 | Dialogue: 0,0:21:06.58,0:21:08.90,English,,0,0,0,,But you see the how tricky the reasoning can get right there's 264 | Dialogue: 0,0:21:09.46,0:21:13.78,English,,0,0,0,,You can't do pattern matching to determine whether you've got races or not races 265 | Dialogue: 0,0:21:14.40,0:21:16.02,English,,0,0,0,,Right so you can't just say well 266 | Dialogue: 0,0:21:16.52,0:21:23.24,English,,0,0,0,,It's always bad to pass the address of some variable to a thread routine 267 | Dialogue: 0,0:21:23.78,0:21:25.72,English,,0,0,0,,Okay because it's not it just depends on the context 268 | Dialogue: 0,0:21:27.37,0:21:31.40,English,,0,0,0,,Okay so in this case we're passing the number of iterations and to each thread and 269 | Dialogue: 0,0:21:33.52,0:21:36.88,English,,0,0,0,,Then we're waiting for each of those threads to finish 270 | Dialogue: 0,0:21:36.90,0:21:43.26,English,,0,0,0,,So this is an example of why you need why you might want to have a non detached thread 271 | Dialogue: 0,0:21:43.30,0:21:43.98,English,,0,0,0,,Because you can't 272 | Dialogue: 0,0:21:46.62,0:21:50.16,English,,0,0,0,,We want when we check when we check the value of count 273 | Dialogue: 0,0:21:50.16,0:21:54.18,English,,0,0,0,,We have to make sure that every thread is finished before we check whether we got the right value or not 274 | Dialogue: 0,0:21:55.28,0:21:56.96,English,,0,0,0,,Okay so we wait for each thread to finish 275 | Dialogue: 0,0:21:58.00,0:22:03.10,English,,0,0,0,,And now since we've created two threads each of which is incrementing count editors time 276 | Dialogue: 0,0:22:04.10,0:22:07.06,English,,0,0,0,,We expect count to be equal to two times and niters 277 | Dialogue: 0,0:22:07.06,0:22:10.44,English,,0,0,0,,And if it's not we print my favorite error message 278 | Dialogue: 0,0:22:11.90,0:22:19.04,English,,0,0,0,,Otherwise we with the value of count,otherwise we print OK also with the value of count 279 | Dialogue: 0,0:22:20.68,0:22:22.64,English,,0,0,0,,Okay so now what's going on in the thread routine 280 | Dialogue: 0,0:22:23.78,0:22:24.54,English,,0,0,0,,Very simple 281 | Dialogue: 0,0:22:26.32,0:22:33.46,English,,0,0,0,,It dereferences the argument that was passed in and stores it in the local copy of entities 282 | Dialogue: 0,0:22:34.84,0:22:36.44,English,,0,0,0,,And then it loop senators time 283 | Dialogue: 0,0:22:37.42,0:22:39.04,English,,0,0,0,,In can increments count each time 284 | Dialogue: 0,0:22:40.20,0:22:41.22,English,,0,0,0,,So and then returns 285 | Dialogue: 0,0:22:42.38,0:22:45.32,English,,0,0,0,,So this is very innocuous what could go wrong 286 | Dialogue: 0,0:22:47.64,0:22:53.22,English,,0,0,0,,And since this is threading,since this is concurrent concurrent programming,especially since it's threaded programming 287 | Dialogue: 0,0:22:53.56,0:22:56.98,English,,0,0,0,,What there's the odd lots of subtle things can go wrong 288 | Dialogue: 0,0:22:56.98,0:23:00.30,English,,0,0,0,,So it turns out this program has a really serious bug 289 | Dialogue: 0,0:23:01.52,0:23:03.48,English,,0,0,0,,Okay because when we run it 290 | Dialogue: 0,0:23:06.24,0:23:08.40,English,,0,0,0,,When we run it on a Linux box 291 | Dialogue: 0,0:23:08.96,0:23:12.80,English,,0,0,0,,Sometimes if we call it with an argument of ten thousand 292 | Dialogue: 0,0:23:13.40,0:23:17.90,English,,0,0,0,,Sometimes we get the correct answer 2*10,000 or 20,000 293 | Dialogue: 0,0:23:18.54,0:23:19.66,English,,0,0,0,,But then the next time we run it 294 | Dialogue: 0,0:23:20.36,0:23:23.76,English,,0,0,0,,We get some weird number 13051 295 | Dialogue: 0,0:23:25.18,0:23:25.94,English,,0,0,0,,Completely wrong 296 | Dialogue: 0,0:23:27.28,0:23:30.18,English,,0,0,0,,And so what the hack is going on here 297 | Dialogue: 0,0:23:32.74,0:23:35.90,English,,0,0,0,,Okay so to understand that we have to look at the assembly language 298 | Dialogue: 0,0:23:37.60,0:23:39.64,English,,0,0,0,,For this counter loop so that 299 | Dialogue: 0,0:23:41.06,0:23:45.94,English,,0,0,0,,We want to...we need to look at the the assembly language for this counter loop in the thread routine 300 | Dialogue: 0,0:23:48.22,0:23:50.34,English,,0,0,0,,So we'll break it up into three chunks that 301 | Dialogue: 0,0:23:51.12,0:23:53.90,English,,0,0,0,,The first chunk is sort of getting ready for the loop 302 | Dialogue: 0,0:23:54.26,0:24:01.60,English,,0,0,0,,We'll call that the head and we'll denote it as H(i) for thread i 303 | Dialogue: 0,0:24:04.94,0:24:12.84,English,,0,0,0,,And then we'll isolate on these three instructions that are directly related to incrementing count 304 | Dialogue: 0,0:24:14.08,0:24:16.22,English,,0,0,0,,Okay so you see the first instruction moves 305 | Dialogue: 0,0:24:16.66,0:24:22.50,English,,0,0,0,,It loads the global of the value and global variable count into register %rdx 306 | Dialogue: 0,0:24:24.14,0:24:25.72,English,,0,0,0,,So will denote that as L(i) 307 | Dialogue: 0,0:24:27.54,0:24:30.18,English,,0,0,0,,Next it increments %rdx 308 | Dialogue: 0,0:24:31.52,0:24:35.98,English,,0,0,0,,And we'll denote that U(i) for update so it updates %rdx 309 | Dialogue: 0,0:24:37.14,0:24:42.92,English,,0,0,0,,And then it stores the value the updated value of %rdx into count 310 | Dialogue: 0,0:24:43.42,0:24:48.06,English,,0,0,0,,Okay so into the location associated with the global variable count 311 | Dialogue: 0,0:24:50.00,0:24:50.44,English,,0,0,0,,And 312 | Dialogue: 0,0:24:53.32,0:24:58.94,English,,0,0,0,,And then the rest of...the rest of this loop is getting ready for the to do the next iteration 313 | Dialogue: 0,0:24:59.70,0:25:02.32,English,,0,0,0,,It's not directly related to incrementing count 314 | Dialogue: 0,0:25:02.32,0:25:06.38,English,,0,0,0,,So we'll just sort of group this all together and refer to it as T(i) for tail 315 | Dialogue: 0,0:25:07.68,0:25:07.86,English,,0,0,0,,Okay 316 | Dialogue: 0,0:25:13.60,0:25:17.56,English,,0,0,0,,Now let's look at...let's look at... 317 | Dialogue: 0,0:25:18.22,0:25:21.94,English,,0,0,0,,How this how these two threads might be executed 318 | Dialogue: 0,0:25:22.12,0:25:27.38,English,,0,0,0,,And remember in general we can't assume that there's any specific interleaving 319 | Dialogue: 0,0:25:27.40,0:25:30.08,English,,0,0,0,,So any interleaving of these two threads is possible 320 | Dialogue: 0,0:25:30.18,0:25:33.32,English,,0,0,0,,No matter how remote it might seem 321 | Dialogue: 0,0:25:34.90,0:25:38.80,English,,0,0,0,,So let's look at one example let's say we're executing on a single core 322 | Dialogue: 0,0:25:38.80,0:25:40.98,English,,0,0,0,,So we're only going to do one instruction at a time 323 | Dialogue: 0,0:25:43.00,0:25:43.54,English,,0,0,0,,And 324 | Dialogue: 0,0:25:45.84,0:25:50.36,English,,0,0,0,,In this column will show which thread is executing so either thread 1 or thread 2 325 | Dialogue: 0,0:25:53.28,0:25:56.42,English,,0,0,0,,And then we'll to know which instruction in that thread is executing 326 | Dialogue: 0,0:25:57.90,0:26:00.28,English,,0,0,0,,Either H,L,U,S or T 327 | Dialogue: 0,0:26:02.02,0:26:07.20,English,,0,0,0,,And then this column shows the value of %rdx for thread number 1 328 | Dialogue: 0,0:26:08.34,0:26:11.46,English,,0,0,0,,And this column shows the value of %rdx for thread number 2 329 | Dialogue: 0,0:26:11.66,0:26:19.28,English,,0,0,0,,Right since that the kernel keeps separate copies of all the general-purpose registers the for each thread these can be different 330 | Dialogue: 0,0:26:22.60,0:26:25.56,English,,0,0,0,,Okay and then this last column shows the value of count in memory 331 | Dialogue: 0,0:26:27.90,0:26:30.82,English,,0,0,0,,So let's start executing 332 | Dialogue: 0,0:26:30.92,0:26:33.06,English,,0,0,0,,So initially count is equal to 0 333 | Dialogue: 0,0:26:34.16,0:26:38.90,English,,0,0,0,,And thread one gets the kernel schedules thread 1 334 | Dialogue: 0,0:26:38.92,0:26:41.94,English,,0,0,0,,So it executes say H(1) that has no impact on count 335 | Dialogue: 0,0:26:43.34,0:26:47.20,English,,0,0,0,,Then thread 1 loads the value of count into its copy of %rdx 336 | Dialogue: 0,0:26:48.52,0:26:49.34,English,,0,0,0,,Updates it 337 | Dialogue: 0,0:26:50.74,0:26:58.90,English,,0,0,0,,So now %rdx is equal to 1 and then stores that value in %rdx back to count so now count is equal to 1 338 | Dialogue: 0,0:27:00.84,0:27:04.20,English,,0,0,0,,Now at this point the kernel decides to schedule thread 2 339 | Dialogue: 0,0:27:04.90,0:27:10.76,English,,0,0,0,,So thread 2 begins executing and when it begins executing value of count is 1 340 | Dialogue: 0,0:27:11.86,0:27:14.20,English,,0,0,0,,So it executes H(i) 341 | Dialogue: 0,0:27:16.26,0:27:22.62,English,,0,0,0,,Then it loads count into thread 2 copy of %rdx 342 | Dialogue: 0,0:27:23.32,0:27:28.08,English,,0,0,0,,So now %rdx equals 1,updates it,now it's equal to 2 343 | Dialogue: 0,0:27:28.68,0:27:31.40,English,,0,0,0,,And then stores that value back to count 344 | Dialogue: 0,0:27:33.20,0:27:41.44,English,,0,0,0,,The kernel then decides oh and then it finishes executing the tail instruction 345 | Dialogue: 0,0:27:42.44,0:27:44.36,English,,0,0,0,,And let's say we're just doing one iteration of this 346 | Dialogue: 0,0:27:45.64,0:27:51.22,English,,0,0,0,,And then at this point the kernel decides to schedule thread 1 since thread 2 is finished so 347 | Dialogue: 0,0:27:51.86,0:27:55.38,English,,0,0,0,,Thread 1 executes the remaining statement that it has to execute 348 | Dialogue: 0,0:27:57.06,0:27:58.82,English,,0,0,0,,And at this point both threads have finished 349 | Dialogue: 0,0:28:00.50,0:28:03.84,English,,0,0,0,,And count is equal to 2 which is the value we would expect 350 | Dialogue: 0,0:28:04.18,0:28:06.74,English,,0,0,0,,Ok so this so this is ok 351 | Dialogue: 0,0:28:07.38,0:28:11.60,English,,0,0,0,,And notice how...so this is actually this is an inner leaving that works 352 | Dialogue: 0,0:28:11.88,0:28:13.08,English,,0,0,0,,Ok we get the correct value 353 | Dialogue: 0,0:28:14.12,0:28:16.02,English,,0,0,0,,And notice how I... 354 | Dialogue: 0,0:28:19.08,0:28:23.14,English,,0,0,0,,I grouped the 3 instructions that are actually involved in updating count together 355 | Dialogue: 0,0:28:24.66,0:28:29.76,English,,0,0,0,,And it will call that,we'll call those 3 instructions a critical section and I've color-coded them 356 | Dialogue: 0,0:28:29.78,0:28:32.02,English,,0,0,0,,So you can easily keep track of them 357 | Dialogue: 0,0:28:34.08,0:28:39.10,English,,0,0,0,,Alright let's look...now let's look at another another interleaving which is feasible right 358 | Dialogue: 0,0:28:40.24,0:28:43.04,English,,0,0,0,,But in this case it results in the wrong value 359 | Dialogue: 0,0:28:44.98,0:28:47.98,English,,0,0,0,,Ok so here we start with thread 1 again 360 | Dialogue: 0,0:28:50.16,0:28:55.52,English,,0,0,0,,It loads it's the value of count into its copy of %rdx updates it 361 | Dialogue: 0,0:28:56.14,0:28:57.62,English,,0,0,0,,But then before it can store it 362 | Dialogue: 0,0:28:59.08,0:29:01.44,English,,0,0,0,,The kernel decides to schedule thread 2 363 | Dialogue: 0,0:29:02.46,0:29:04.84,English,,0,0,0,,So thread 2 begins x executing 364 | Dialogue: 0,0:29:05.86,0:29:09.28,English,,0,0,0,,It loads count into its copy of %rdx too 365 | Dialogue: 0,0:29:10.18,0:29:14.24,English,,0,0,0,,And notice count is still 0 right it's 1 366 | Dialogue: 0,0:29:15.84,0:29:19.64,English,,0,0,0,,In the value of in thread 1 in the %rdx 367 | Dialogue: 0,0:29:20.12,0:29:24.02,English,,0,0,0,,The copy of %rdx and thread 1 but it hasn't been updated in memory so 368 | Dialogue: 0,0:29:24.98,0:29:29.92,English,,0,0,0,,When thread 2 loads its value of count 369 | Dialogue: 0,0:29:29.92,0:29:33.44,English,,0,0,0,,Now it's copy and %rdx is 0 370 | Dialogue: 0,0:29:34.60,0:29:39.72,English,,0,0,0,,Now at this point the kernel reschedules thread 1 to execute so thread 1 does it store 371 | Dialogue: 0,0:29:40.88,0:29:43.98,English,,0,0,0,,Of its copy of %rdx into count 372 | Dialogue: 0,0:29:44.96,0:29:48.16,English,,0,0,0,,And then finishes executing it the tail instruction 373 | Dialogue: 0,0:29:49.44,0:29:54.72,English,,0,0,0,,The colonel reschedules thread 2 which picks up where it left off it updates 374 | Dialogue: 0,0:29:55.90,0:29:58.36,English,,0,0,0,,Its copy of count 375 | Dialogue: 0,0:29:58.46,0:30:01.60,English,,0,0,0,,So now %rdx goes from 0 to 1 376 | Dialogue: 0,0:30:03.18,0:30:06.12,English,,0,0,0,,And then it stores that value into count 377 | Dialogue: 0,0:30:06.80,0:30:10.44,English,,0,0,0,,So all we've done is we've overwritten count out a value 1 378 | Dialogue: 0,0:30:11.06,0:30:12.80,English,,0,0,0,,And we've overwritten it with a value of 1 379 | Dialogue: 0,0:30:13.82,0:30:17.72,English,,0,0,0,,So when we finish execution of these two threads count has the wrong value 380 | Dialogue: 0,0:30:20.58,0:30:21.18,English,,0,0,0,,Okay in the 381 | Dialogue: 0,0:30:22.58,0:30:27.96,English,,0,0,0,,That then the general like,the general thing to notice is you see how these critical sections have been interleaved 382 | Dialogue: 0,0:30:28.64,0:30:30.72,English,,0,0,0,,Right in this case 383 | Dialogue: 0,0:30:32.14,0:30:37.60,English,,0,0,0,,This is the first the critical section for thread 1 executed before the critical section for thread 2 384 | Dialogue: 0,0:30:39.52,0:30:42.88,English,,0,0,0,,Okay but in this case the two critical sections interleaved okay 385 | Dialogue: 0,0:30:46.24,0:30:48.30,English,,0,0,0,,So let's see another example of that 386 | Dialogue: 0,0:30:48.70,0:30:50.78,English,,0,0,0,,So here you can see that these are interleaved so 387 | Dialogue: 0,0:30:53.60,0:30:55.10,English,,0,0,0,,Probably suggest there might be a problem.Yes! 388 | Dialogue: 0,0:30:55.12,0:31:00.68,English,,0,0,0,,[student speaking] 389 | Dialogue: 0,0:31:00.68,0:31:01.98,English,,0,0,0,,So I'm sorry excuse me 390 | Dialogue: 0,0:31:02.04,0:31:11.32,English,,0,0,0,,[student speaking] 391 | Dialogue: 0,0:31:11.34,0:31:13.72,English,,0,0,0,,Well no okay so the question is would would 392 | Dialogue: 0,0:31:14.90,0:31:15.60,English,,0,0,0,,I or count count 393 | Dialogue: 0,0:31:22.10,0:31:26.10,English,,0,0,0,,If we...okay it is defined as volatile 394 | Dialogue: 0,0:31:28.52,0:31:37.68,English,,0,0,0,,Yeah so that that's why...I mean there's actually and the compiler could have compiled this code in different ways right 395 | Dialogue: 0,0:31:38.10,0:31:42.96,English,,0,0,0,,There is actually an increment instruction that you will increment a variable in memory 396 | Dialogue: 0,0:31:43.16,0:31:44.36,English,,0,0,0,,So you could have done 397 | Dialogue: 0,0:31:45.60,0:31:47.10,English,,0,0,0,,The compiler could have generated this 398 | Dialogue: 0,0:31:47.36,0:31:51.10,English,,0,0,0,,This 3 instruction sequence is one instruction and then we wouldn't have this problem 399 | Dialogue: 0,0:31:51.64,0:31:52.62,English,,0,0,0,,But the problem is that 400 | Dialogue: 0,0:31:53.68,0:31:59.86,English,,0,0,0,,It's loading into register then incrementing and then saving 401 | Dialogue: 0,0:31:59.88,0:32:01.78,English,,0,0,0,,So that the problem comes about because 402 | Dialogue: 0,0:32:02.26,0:32:02.64,English,,0,0,0,,We can 403 | Dialogue: 0,0:32:05.08,0:32:10.02,English,,0,0,0,,This thread can be interrupted before it finishes this three-step sequence 404 | Dialogue: 0,0:32:10.02,0:32:12.20,English,,0,0,0,,This load modify store sequence 405 | Dialogue: 0,0:32:12.98,0:32:13.28,English,,0,0,0,,Yes 406 | Dialogue: 0,0:32:13.66,0:32:21.36,English,,0,0,0,,[student speaking] 407 | Dialogue: 0,0:32:21.36,0:32:24.86,English,,0,0,0,,It would wait yeah so it that's right yeah I guess I wasn't clear it 408 | Dialogue: 0,0:32:25.63,0:32:28.66,English,,0,0,0,,It prevents it from being stored permanently in a register right so 409 | Dialogue: 0,0:32:29.42,0:32:34.24,English,,0,0,0,,It may have to be loaded into a register but then it'll be written back 410 | Dialogue: 0,0:32:36.02,0:32:39.52,English,,0,0,0,,Okay whereas the the compiler would have the option like we've seen it with local variables 411 | Dialogue: 0,0:32:40.16,0:32:43.44,English,,0,0,0,,Right the compiler just it never allocates stack space 412 | Dialogue: 0,0:32:43.44,0:32:45.88,English,,0,0,0,,It just keeps that local variable in a register all the time 413 | Dialogue: 0,0:32:46.12,0:32:50.02,English,,0,0,0,,Okay so this prevent the volatile attribute prevents the compiler from doing that 414 | Dialogue: 0,0:32:55.58,0:32:57.19,English,,0,0,0,,Okay so let's look at another example 415 | Dialogue: 0,0:32:58.20,0:33:00.58,English,,0,0,0,,So here thread 1 starts 416 | Dialogue: 0,0:33:01.08,0:33:04.24,English,,0,0,0,,It loads count into %rdx 417 | Dialogue: 0,0:33:05.08,0:33:06.28,English,,0,0,0,,Then thread 2 starts 418 | Dialogue: 0,0:33:07.36,0:33:11.44,English,,0,0,0,,And it loads a count which is still 0 into %rdx(2) 419 | Dialogue: 0,0:33:12.18,0:33:15.80,English,,0,0,0,,Updates it and then stores it so now count equal to 1 420 | Dialogue: 0,0:33:16.38,0:33:25.56,English,,0,0,0,,When thread 1 resumes it updates its value of count and %rdx and stores that back to count 421 | Dialogue: 0,0:33:25.92,0:33:28.22,English,,0,0,0,,And so again we have the same problem 422 | Dialogue: 0,0:33:30.58,0:33:31.34,English,,0,0,0,,Okay so the... 423 | Dialogue: 0,0:33:32.52,0:33:36.22,English,,0,0,0,,The problem here is that we're interleaving these these critical sections 424 | Dialogue: 0,0:33:36.92,0:33:39.62,English,,0,0,0,,And you can understand why this is bad 425 | Dialogue: 0,0:33:40.74,0:33:43.60,English,,0,0,0,,With a nice or graphical technique called a progress graph 426 | Dialogue: 0,0:33:48.38,0:33:49.96,English,,0,0,0,,So in a progress graph 427 | Dialogue: 0,0:33:52.60,0:33:56.20,English,,0,0,0,,If we have 4n threads it's an n dimensional cartesian grid 428 | Dialogue: 0,0:33:57.98,0:34:03.88,English,,0,0,0,,That characterizes the execution state space of a concurrent threaded program 429 | Dialogue: 0,0:34:05.06,0:34:07.58,English,,0,0,0,,So in this case each here we have two threads 430 | Dialogue: 0,0:34:07.60,0:34:12.06,English,,0,0,0,,So it's a 2d coordinate system 431 | Dialogue: 0,0:34:13.04,0:34:18.36,English,,0,0,0,,So each axis represents the progress the execution progress of some threads 432 | Dialogue: 0,0:34:18.44,0:34:22.52,English,,0,0,0,,So the x axis here is thread 1 433 | Dialogue: 0,0:34:23.08,0:34:25.72,English,,0,0,0,,And the y axis corresponds to thread 2 434 | Dialogue: 0,0:34:27.40,0:34:32.16,English,,0,0,0,,And then each one of these edges corresponds to the execution of an instruction 435 | Dialogue: 0,0:34:32.88,0:34:35.34,English,,0,0,0,,Ok so we start out in an initial state 436 | Dialogue: 0,0:34:36.12,0:34:38.50,English,,0,0,0,,And then the first thing we execute is H(1) 437 | Dialogue: 0,0:34:39.70,0:34:42.21,English,,0,0,0,,So that's represented by this ACK here 438 | Dialogue: 0,0:34:43.18,0:34:47.64,English,,0,0,0,,So this position this point right here represents the state where 439 | Dialogue: 0,0:34:48.26,0:34:52.94,English,,0,0,0,,We've executed H,we finished executing H(1) in thread 1 440 | Dialogue: 0,0:34:52.94,0:34:56.18,English,,0,0,0,,But we haven't yet executed any instructions in thread 2 441 | Dialogue: 0,0:34:57.56,0:35:00.30,English,,0,0,0,,Ok so in general each one of these points represents 442 | Dialogue: 0,0:35:01.98,0:35:05.08,English,,0,0,0,,Sort of the current progress of the program or the execution state 443 | Dialogue: 0,0:35:06.06,0:35:11.02,English,,0,0,0,,So for example this state right here represents the state where thread 1 444 | Dialogue: 0,0:35:11.34,0:35:13.60,English,,0,0,0,,Has completed a completed L1 445 | Dialogue: 0,0:35:14.24,0:35:17.16,English,,0,0,0,,And thread 2 is completed S(2) 446 | Dialogue: 0,0:35:22.30,0:35:28.16,English,,0,0,0,,And now the execution of a program is modeled as a transition from one state to the other 447 | Dialogue: 0,0:35:28.78,0:35:33.66,English,,0,0,0,,And there's some,so from this and there's constraints on how 448 | Dialogue: 0,0:35:34.82,0:35:39.00,English,,0,0,0,,On how these states can advance so 449 | Dialogue: 0,0:35:39.74,0:35:41.62,English,,0,0,0,,From this state(L1, S2) 450 | Dialogue: 0,0:35:42.56,0:35:50.10,English,,0,0,0,,Obviously time can't go backwards right so we can't go backwards like in this direction to the left and we can't go down 451 | Dialogue: 0,0:35:50.78,0:35:53.48,English,,0,0,0,,Okay so we can only go to the right and up 452 | Dialogue: 0,0:35:54.56,0:35:56.96,English,,0,0,0,,And since we're assuming that each instruction executes 453 | Dialogue: 0,0:35:57.58,0:36:00.18,English,,0,0,0,,There's only one instruction executing at a time 454 | Dialogue: 0,0:36:00.58,0:36:03.12,English,,0,0,0,,We can't go diagonally that would be two instructions 455 | Dialogue: 0,0:36:03.62,0:36:05.26,English,,0,0,0,,All right so from (L1,S2) 456 | Dialogue: 0,0:36:05.90,0:36:08.08,English,,0,0,0,,The next execution state is either 457 | Dialogue: 0,0:36:09.46,0:36:15.26,English,,0,0,0,,Here if thread one execute or here if thread of thread to execute 458 | Dialogue: 0,0:36:17.54,0:36:20.28,English,,0,0,0,,Okay so you can put all these together to form a trajectory 459 | Dialogue: 0,0:36:20.92,0:36:24.02,English,,0,0,0,,Which characterizes one execution of the program 460 | Dialogue: 0,0:36:25.86,0:36:32.76,English,,0,0,0,,Right and any feasible set of transitions from one state to the next corresponds to a feasible trajectory 461 | Dialogue: 0,0:36:34.46,0:36:50.60,English,,0,0,0,,So for example H(1),L(1),U(1),H(2),L(2),S(1),T(1),U(2),S(2),T(2) 462 | Dialogue: 0,0:36:51.42,0:36:52.58,English,,0,0,0,,That's a feasible 463 | Dialogue: 0,0:36:55.20,0:36:56.52,English,,0,0,0,,That's a feasible trajectory 464 | Dialogue: 0,0:36:57.58,0:37:06.38,English,,0,0,0,,And it's one possible it represents one possible execution or so one set of inter leavings for this program 465 | Dialogue: 0,0:37:10.42,0:37:16.82,English,,0,0,0,,Now these L these three instructions L,U and S that operate on that manipulate count 466 | Dialogue: 0,0:37:17.40,0:37:20.66,English,,0,0,0,,Form what we call a critical section with respect to count 467 | Dialogue: 0,0:37:25.18,0:37:29.20,English,,0,0,0,,And the idea is that instructions inside 468 | Dialogue: 0,0:37:29.54,0:37:36.50,English,,0,0,0,,These critical sections this with receivership with respect to the same global variable shouldn't be interleaved 469 | Dialogue: 0,0:37:38.28,0:37:43.70,English,,0,0,0,,So we can capture this geometrically by taking the intersection of these critical sections 470 | Dialogue: 0,0:37:44.48,0:37:47.18,English,,0,0,0,,To form what we call an unsafe region 471 | Dialogue: 0,0:37:48.90,0:37:53.10,English,,0,0,0,,So in this an unsafe region is... 472 | Dialogue: 0,0:37:53.66,0:38:01.66,English,,0,0,0,,The points within an unsafe region are those points in an execution where the critical sections are being or interleaved 473 | Dialogue: 0,0:38:03.26,0:38:07.32,English,,0,0,0,,Okay so for this particular example there's four points within the unsafe region 474 | Dialogue: 0,0:38:08.24,0:38:10.72,English,,0,0,0,,And if a trajectory ever touches one of those points 475 | Dialogue: 0,0:38:10.72,0:38:13.70,English,,0,0,0,,Then we've interleaved critical section and we're going to get the wrong answer 476 | Dialogue: 0,0:38:17.12,0:38:19.90,English,,0,0,0,,Okay so the idea is to try to stay out of these unsafe regions 477 | Dialogue: 0,0:38:25.28,0:38:28.40,English,,0,0,0,,And if we do we say that trajectory is safe so 478 | Dialogue: 0,0:38:29.50,0:38:31.96,English,,0,0,0,,Here's an example of a trajectory that's safe 479 | Dialogue: 0,0:38:33.20,0:38:37.04,English,,0,0,0,,Now this is okay,right this point right here is not in the unsafe region 480 | Dialogue: 0,0:38:37.82,0:38:40.62,English,,0,0,0,,Because we haven't executed we only executed H(1) here 481 | Dialogue: 0,0:38:41.16,0:38:43.42,English,,0,0,0,,Remember a point corresponds to 482 | Dialogue: 0,0:38:43.88,0:38:48.82,English,,0,0,0,,And it's the instruction that we've completed that instruction 483 | Dialogue: 0,0:38:51.10,0:38:51.86,English,,0,0,0,,So then 484 | Dialogue: 0,0:38:53.12,0:38:55.08,English,,0,0,0,,So here we're skirting the unsafe region 485 | Dialogue: 0,0:38:55.08,0:38:58.88,English,,0,0,0,,But it's still okay,so this is a safe trajectory we'll get the right answer for this one 486 | Dialogue: 0,0:39:00.00,0:39:00.82,English,,0,0,0,,However 487 | Dialogue: 0,0:39:03.58,0:39:05.52,English,,0,0,0,,This trajectory is unsafe because it 488 | Dialogue: 0,0:39:07.82,0:39:11.10,English,,0,0,0,,It enters the unsafe region at this point here 489 | Dialogue: 0,0:39:12.66,0:39:20.40,English,,0,0,0,,And even though it quickly exited the there's an interleaving there that creates a potential for a correct answer 490 | Dialogue: 0,0:39:27.54,0:39:31.50,English,,0,0,0,,Okay so the question is how do we guarantee a safe trajectory 491 | Dialogue: 0,0:39:31.58,0:39:33.98,English,,0,0,0,,And this is the this is what we call synchronization 492 | Dialogue: 0,0:39:34.00,0:39:39.67,English,,0,0,0,,So somehow we want to sort of configure the kernel 493 | Dialogue: 0,0:39:40.58,0:39:43.10,English,,0,0,0,,So that'll never schedule an unsafe trajectory 494 | Dialogue: 0,0:39:45.86,0:39:46.78,English,,0,0,0,,So how do we do that 495 | Dialogue: 0,0:39:47.88,0:39:50.20,English,,0,0,0,,So somehow 496 | Dialogue: 0,0:39:51.52,0:39:54.98,English,,0,0,0,,We we have to synchronize the execution of those threads 497 | Dialogue: 0,0:39:55.66,0:40:02.44,English,,0,0,0,,And another way to think of this is that we need to guarantee mutually exclusive access to the critical sections 498 | Dialogue: 0,0:40:03.22,0:40:10.48,English,,0,0,0,,All right so once the kernel begins,once the thread starts executing the first instruction is critical section 499 | Dialogue: 0,0:40:10.88,0:40:16.14,English,,0,0,0,,We don't want it to be interrupted by another thread that has a similar critical section 500 | Dialogue: 0,0:40:16.32,0:40:17.76,English,,0,0,0,,Okay we don't want it to be interrupted 501 | Dialogue: 0,0:40:18.14,0:40:22.22,English,,0,0,0,,We don't want...one critical section with respect to a certain global variable 502 | Dialogue: 0,0:40:23.16,0:40:29.36,English,,0,0,0,,To be interrupted by another thread that has all right that's currently within that same critical section okay 503 | Dialogue: 0,0:40:30.62,0:40:31.50,English,,0,0,0,,Sorry yes question 504 | Dialogue: 0,0:40:31.50,0:40:45.08,English,,0,0,0,,Seems unlikely for me that 505 | Dialogue: 0,0:40:45.08,0:40:48.44,English,,0,0,0,,Okay so the question is how likely is it that you get a correct trajectory 506 | Dialogue: 0,0:40:48.48,0:40:51.02,English,,0,0,0,,And it happens right you can run it sometimes you do 507 | Dialogue: 0,0:40:51.54,0:40:55.20,English,,0,0,0,,It just depends usually it's wrong sometimes it's right 508 | Dialogue: 0,0:40:57.96,0:41:03.92,English,,0,0,0,,And it just depends on how the kernel scheduled it and you can't assume any particular scheduling 509 | Dialogue: 0,0:41:04.80,0:41:09.86,English,,0,0,0,,Right so if you say, if you want to claim that you would never get the right answer 510 | Dialogue: 0,0:41:10.48,0:41:15.04,English,,0,0,0,,Then you're assuming that the kernel is always going to schedule the unsafe trajectory but 511 | Dialogue: 0,0:41:15.68,0:41:18.72,English,,0,0,0,,You can't assume that in fact it doesn't sometimes you just get lucky 512 | Dialogue: 0,0:41:23.70,0:41:29.96,English,,0,0,0,,And it turns out you have to call this function with a pretty big number in order to trip it up 513 | Dialogue: 0,0:41:32.06,0:41:33.92,English,,0,0,0,,So the it makes sense right 514 | Dialogue: 0,0:41:34.92,0:41:39.14,English,,0,0,0,,If usually what the kernel does is that 515 | Dialogue: 0,0:41:40.30,0:41:42.28,English,,0,0,0,,I we can only schedule 516 | Dialogue: 0,0:41:43.12,0:41:47.48,English,,0,0,0,,We can only reschedule a thread you know swap it out and schedule another thread in 517 | Dialogue: 0,0:41:47.96,0:41:52.92,English,,0,0,0,,When there's some exception okay so that that passes control back to the kernel 518 | Dialogue: 0,0:41:54.70,0:41:59.76,English,,0,0,0,,So these exceptions are in two forms either calling system making system calls 519 | Dialogue: 0,0:41:59.96,0:42:03.38,English,,0,0,0,,So that'll trap into the kernel so that's a form of exception 520 | Dialogue: 0,0:42:03.86,0:42:09.50,English,,0,0,0,,Or the timer interrupts goes off which transfers control back to the kernel 521 | Dialogue: 0,0:42:10.36,0:42:14.88,English,,0,0,0,,So the timer is going off on intervals of like milliseconds 522 | Dialogue: 0,0:42:16.44,0:42:20.76,English,,0,0,0,,Right so if we're just doing one iteration it in each thread 523 | Dialogue: 0,0:42:20.94,0:42:26.10,English,,0,0,0,,When a thread gets executed the chances are very low that the timer is going to go off 524 | Dialogue: 0,0:42:27.14,0:42:30.56,English,,0,0,0,,While that thread is executing you know it's its little loop 525 | Dialogue: 0,0:42:32.86,0:42:35.12,English,,0,0,0,,But as we...and we're not making any system calls 526 | Dialogue: 0,0:42:35.28,0:42:42.30,English,,0,0,0,,Right so there's nothing that, there's nothing...we're not passing control back into the kernel ourselves 527 | Dialogue: 0,0:42:43.14,0:42:47.68,English,,0,0,0,,So the only way the kernel is going to get access is if the timer interrupts goes off 528 | Dialogue: 0,0:42:48.86,0:42:51.28,English,,0,0,0,,So if we're doing a very small number of iterations 529 | Dialogue: 0,0:42:52.22,0:42:57.00,English,,0,0,0,,The probability that you know say here's the timer interval it's going off at intervals like this 530 | Dialogue: 0,0:42:58.10,0:43:01.86,English,,0,0,0,,Here this the probability we'd have to 531 | Dialogue: 0,0:43:02.60,0:43:08.94,English,,0,0,0,,That's thread would have to been scheduled right before a timer interrupts will go off or to interrupt that one or two iterations 532 | Dialogue: 0,0:43:09.86,0:43:11.36,English,,0,0,0,,So it turns out we have to schedule 533 | Dialogue: 0,0:43:12.12,0:43:16.70,English,,0,0,0,,We have to call this function with a lot of within interrupts being fairly large 534 | Dialogue: 0,0:43:17.28,0:43:22.52,English,,0,0,0,,So that the probability of the timer interrupts going off during that 535 | Dialogue: 0,0:43:23.34,0:43:28.60,English,,0,0,0,,During that during that loop but gets increasingly large,that makes sense 536 | Dialogue: 0,0:43:36.16,0:43:39.26,English,,0,0,0,,So the classic solution from this comes from the early 1960s 537 | Dialogue: 0,0:43:39.26,0:43:46.38,English,,0,0,0,,One of the most famous computer scientists is a dutchman named as Edsger Dijkstra 538 | Dialogue: 0,0:43:47.38,0:43:53.38,English,,0,0,0,,And he came up with the classical first solution to this problem which is what we're going to look at 539 | Dialogue: 0,0:43:54.18,0:43:57.60,English,,0,0,0,,Okay and it's still the first it's it's fundamental and very general purpose 540 | Dialogue: 0,0:43:57.60,0:44:01.76,English,,0,0,0,,And there's been many iterations and variations on this idea 541 | Dialogue: 0,0:44:02.74,0:44:08.00,English,,0,0,0,,But semaphores were the first and classic solution which we'll look at 542 | Dialogue: 0,0:44:11.38,0:44:17.58,English,,0,0,0,,Okay so a semaphore is a non-negative global integer 543 | Dialogue: 0,0:44:17.68,0:44:24.14,English,,0,0,0,,That's used as a synchronization variable by to kernel functions called P and V 544 | Dialogue: 0,0:44:27.12,0:44:28.98,English,,0,0,0,,Our two system calls called P and V 545 | Dialogue: 0,0:44:32.38,0:44:36.60,English,,0,0,0,,These P and V are correspond to the dutch words 546 | Dialogue: 0,0:44:38.74,0:44:43.72,English,,0,0,0,,But we just call them P and V right you just have to learn what they do 547 | Dialogue: 0,0:44:46.74,0:44:51.06,English,,0,0,0,,So each of these takes as an argument a semaphore 548 | Dialogue: 0,0:44:52.84,0:44:56.82,English,,0,0,0,,And the P operation has the following semantics 549 | Dialogue: 0,0:44:58.28,0:45:00.54,English,,0,0,0,,If s is nonzero 550 | Dialogue: 0,0:45:02.30,0:45:04.96,English,,0,0,0,,Then decrement it by 1 and return immediately 551 | Dialogue: 0,0:45:07.68,0:45:10.60,English,,0,0,0,,And this test if it that it's nonzero 552 | Dialogue: 0,0:45:11.38,0:45:13.16,English,,0,0,0,,And the decrement occur atomically 553 | Dialogue: 0,0:45:13.92,0:45:15.54,English,,0,0,0,,Okay so they'll never be interrupted 554 | Dialogue: 0,0:45:20.28,0:45:21.96,English,,0,0,0,,However if s is zero 555 | Dialogue: 0,0:45:24.10,0:45:25.58,English,,0,0,0,,Then suspend this thread 556 | Dialogue: 0,0:45:26.84,0:45:29.40,English,,0,0,0,,Until s becomes nonzero 557 | Dialogue: 0,0:45:31.10,0:45:34.26,English,,0,0,0,,And that thread then is restarted by a V operation 558 | Dialogue: 0,0:45:36.94,0:45:41.86,English,,0,0,0,,Okay so if p if the semaphore is zero,P just blocks 559 | Dialogue: 0,0:45:42.32,0:45:46.74,English,,0,0,0,,It just gets suspended until it gets restarted by a V operation 560 | Dialogue: 0,0:45:48.10,0:45:49.44,English,,0,0,0,,And then after it restarts 561 | Dialogue: 0,0:45:50.18,0:45:57.20,English,,0,0,0,,The P operation now can decrement s by one and return control to the caller 562 | Dialogue: 0,0:46:03.26,0:46:06.00,English,,0,0,0,,Okay the V operation just increments s by one 563 | Dialogue: 0,0:46:06.92,0:46:13.60,English,,0,0,0,,And this increment unlike that count++ that we looked at just looked at this that increment occurs atomically 564 | Dialogue: 0,0:46:14.60,0:46:16.12,English,,0,0,0,,Okay so it can never be interrupted 565 | Dialogue: 0,0:46:18.02,0:46:19.98,English,,0,0,0,,And then after it increments s 566 | Dialogue: 0,0:46:21.06,0:46:24.84,English,,0,0,0,,It checks to see if there's any threads that are blocked in a P operation 567 | Dialogue: 0,0:46:25.26,0:46:30.66,English,,0,0,0,,So you can think of the kernel just keeps a queue of threads that are blocked in a P operation 568 | Dialogue: 0,0:46:31.40,0:46:37.38,English,,0,0,0,,And the V operation after it increments s it checks that queue for any threads that were blocked 569 | Dialogue: 0,0:46:38.50,0:46:41.44,English,,0,0,0,,Because when they did the P operation the semaphore was zero 570 | Dialogue: 0,0:46:43.06,0:46:47.32,English,,0,0,0,,And then it restarts exactly one of those threads in some indeterminate order 571 | Dialogue: 0,0:46:47.44,0:46:50.68,English,,0,0,0,,Okay in some order that you can't,you can't assume 572 | Dialogue: 0,0:46:51.10,0:46:54.90,English,,0,0,0,,It just picks one using some selection algorithm 573 | Dialogue: 0,0:46:56.38,0:47:05.64,English,,0,0,0,,And it and then it it it unblocks the suspended the suspended process 574 | Dialogue: 0,0:47:07.88,0:47:11.16,English,,0,0,0,,Okay which then completes its P operation by decrementing yes 575 | Dialogue: 0,0:47:17.62,0:47:22.68,English,,0,0,0,,Okay this seems like really simple but it can be kind of hard to get your head around the first time you see it 576 | Dialogue: 0,0:47:23.62,0:47:26.64,English,,0,0,0,,So are there any questions about P and V 577 | Dialogue: 0,0:47:34.72,0:47:41.62,English,,0,0,0,,Okay so that the key idea that these definitions of P and V 578 | Dialogue: 0,0:47:42.40,0:47:46.08,English,,0,0,0,,Is that it imposes an invariant on the semaphores 579 | Dialogue: 0,0:47:46.84,0:47:50.68,English,,0,0,0,,Called the semaphore invariant which is s which is that for a semaphore s 580 | Dialogue: 0,0:47:52.66,0:47:55.10,English,,0,0,0,,Being operated on by P and V operations 581 | Dialogue: 0,0:47:55.64,0:47:57.52,English,,0,0,0,,s is always greater than or equal to zero 582 | Dialogue: 0,0:48:01.12,0:48:02.66,English,,0,0,0,,And that doesn't seem very exciting 583 | Dialogue: 0,0:48:03.82,0:48:11.40,English,,0,0,0,,But it turns out this is a very useful property that will allow us to enforce mutual exclusion on these critical sections 584 | Dialogue: 0,0:48:13.64,0:48:18.24,English,,0,0,0,,So the P and V operations are provided by P threads 585 | Dialogue: 0,0:48:19.24,0:48:21.28,English,,0,0,0,,In the form of three functions 586 | Dialogue: 0,0:48:21.42,0:48:25.50,English,,0,0,0,,There's a sem_init functions which initializes the semaphore to some value 587 | Dialogue: 0,0:48:26.22,0:48:31.92,English,,0,0,0,,Okay so semaphore is can be initialized to any value greater than or equal to zero 588 | Dialogue: 0,0:48:34.04,0:48:39.86,English,,0,0,0,,sem_wait is the P operation and sem_post is the V operation 589 | Dialogue: 0,0:48:41.88,0:48:44.38,English,,0,0,0,,Okay and because I'm old-school 590 | Dialogue: 0,0:48:45.38,0:48:51.48,English,,0,0,0,,I provide wrapper functions for those in your cssapp.h file called P and V 591 | Dialogue: 0,0:48:52.72,0:48:53.86,English,,0,0,0,,Okay it's also more compact to 592 | Dialogue: 0,0:49:00.20,0:49:07.02,English,,0,0,0,,Okay so recall a buggy program called badcnt.c 593 | Dialogue: 0,0:49:07.80,0:49:11.76,English,,0,0,0,,Which was giving us the wrong answers for count 594 | Dialogue: 0,0:49:13.30,0:49:15.82,English,,0,0,0,,So how do we use semaphores to fix this program 595 | Dialogue: 0,0:49:18.92,0:49:21.46,English,,0,0,0,,So the basic idea is to create a semaphore 596 | Dialogue: 0,0:49:22.20,0:49:23.86,English,,0,0,0,,Which is initialized to 1 597 | Dialogue: 0,0:49:25.70,0:49:29.80,English,,0,0,0,,And so by definition we'll call any semaphore which is initialized to 1 598 | Dialogue: 0,0:49:29.82,0:49:33.36,English,,0,0,0,,That's used for to provide mutual exclusion we'll call that a mutex 599 | Dialogue: 0,0:49:34.98,0:49:38.06,English,,0,0,0,,Okay and this goes back to the early Dijkstra papers 600 | Dialogue: 0,0:49:39.62,0:49:47.62,English,,0,0,0,,So we'll associate a unique mutex initialize to 1 for each shared variable in our program 601 | Dialogue: 0,0:49:48.98,0:49:53.80,English,,0,0,0,,So in this case count,we have count,so we have one shared variable that we're concerned about 602 | Dialogue: 0,0:49:54.42,0:49:57.76,English,,0,0,0,,So we'll create one new text that will call mutex 603 | Dialogue: 0,0:49:59.00,0:50:03.48,English,,0,0,0,,And then you surround the critical section with respect to count 604 | Dialogue: 0,0:50:04.20,0:50:10.94,English,,0,0,0,,With P, you call P then you execute the critical section and then you call V 605 | Dialogue: 0,0:50:15.44,0:50:19.20,English,,0,0,0,,Now there's some terminology we'll use when we talk about semaphores 606 | Dialogue: 0,0:50:20.08,0:50:25.26,English,,0,0,0,,So a binary semaphore is the semaphore whose value is always 0 1 607 | Dialogue: 0,0:50:25.72,0:50:31.08,English,,0,0,0,,And then a mutex is this sort is a binary semaphore that's being used to for mutual exclusion 608 | Dialogue: 0,0:50:33.42,0:50:35.44,English,,0,0,0,,The P operation is called locking the mutex 609 | Dialogue: 0,0:50:37.74,0:50:41.32,English,,0,0,0,,Will refer to a V is sometimes unlocking or releasing the mutex 610 | Dialogue: 0,0:50:42.52,0:50:50.38,English,,0,0,0,,And if a process is holding the mutex then that means it's been locked but not released 611 | Dialogue: 0,0:50:53.26,0:50:56.80,English,,0,0,0,,So mutexes and binary semaphore s are always initialized to 1 612 | Dialogue: 0,0:50:57.20,0:51:02.98,English,,0,0,0,,Accounting semaphore and the mutex is used for mutual exclusion 613 | Dialogue: 0,0:51:03.00,0:51:06.58,English,,0,0,0,,But you can also use semaphores to count sort of events in the system 614 | Dialogue: 0,0:51:07.80,0:51:15.98,English,,0,0,0,,And often times for those accounting semaphores have sort of non values that are greater than 1 615 | Dialogue: 0,0:51:19.74,0:51:21.30,English,,0,0,0,,Okay so for mutual exclusion 616 | Dialogue: 0,0:51:23.66,0:51:28.94,English,,0,0,0,,We'll to fix our program we create a new program called goodcnt.c 617 | Dialogue: 0,0:51:30.46,0:51:32.70,English,,0,0,0,,And here we initialize a mutex 618 | Dialogue: 0,0:51:33.72,0:51:36.40,English,,0,0,0,,Or we create a mutex and initialize it to 1 619 | Dialogue: 0,0:51:38.72,0:51:43.88,English,,0,0,0,,And then we surround the critical section which is the 3 assembly language instructions 620 | Dialogue: 0,0:51:44.36,0:51:47.68,English,,0,0,0,,Embodied that implement this cnt++ instruction 621 | Dialogue: 0,0:51:48.42,0:51:51.36,English,,0,0,0,,We surround it with a P followed by it by a V 622 | Dialogue: 0,0:51:54.28,0:51:57.24,English,,0,0,0,,And if we do that we always get the right answer 623 | Dialogue: 0,0:52:00.52,0:52:03.46,English,,0,0,0,,But you know P&V are system calls 624 | Dialogue: 0,0:52:03.99,0:52:05.46,English,,0,0,0,,So there's overhead associated with these 625 | Dialogue: 0,0:52:05.46,0:52:06.28,English,,0,0,0,,So they're not free 626 | Dialogue: 0,0:52:06.48,0:52:11.84,English,,0,0,0,,In fact they're orders of magnitude this program runs two orders of magnitude slower than the incorrect buggy version 627 | Dialogue: 0,0:52:13.56,0:52:15.60,English,,0,0,0,,All right so so why do these mutex work 628 | Dialogue: 0,0:52:19.98,0:52:26.34,English,,0,0,0,,So here we've got a progress graph now where we've decorated a program with P and V operations 629 | Dialogue: 0,0:52:26.34,0:52:33.86,English,,0,0,0,,So we put the P before the critical section we execute the critical section and then we call V 630 | Dialogue: 0,0:52:35.96,0:52:39.22,English,,0,0,0,,And now if you were to look you remember P and V,P increments 631 | Dialogue: 0,0:52:40.52,0:52:44.72,English,,0,0,0,,The sum of P decrement the semaphore V increments of semaphore 632 | Dialogue: 0,0:52:45.68,0:52:53.54,English,,0,0,0,,So if you were just to look at the value of that semaphore for every point in the execution state space 633 | Dialogue: 0,0:52:54.90,0:52:57.94,English,,0,0,0,,You'd get these,you'd get these values 634 | Dialogue: 0,0:52:57.96,0:53:03.12,English,,0,0,0,,So here we initialize the semaphore at the origin we initialized it to 1 635 | Dialogue: 0,0:53:03.14,0:53:10.16,English,,0,0,0,,So the value of a semaphore at the origin is 1 636 | Dialogue: 0,0:53:11.38,0:53:13.10,English,,0,0,0,,And let's say we just move along 637 | Dialogue: 0,0:53:13.12,0:53:14.78,English,,0,0,0,,So we're just executing thread 1 638 | Dialogue: 0,0:53:14.78,0:53:17.18,English,,0,0,0,,So after H(1) the semaphore is 1 639 | Dialogue: 0,0:53:19.02,0:53:25.04,English,,0,0,0,,We do the P the semaphore is 1,so P just decrement sit and it proceeds 640 | Dialogue: 0,0:53:25.50,0:53:28.76,English,,0,0,0,,So now the semaphore value becomes 0 641 | Dialogue: 0,0:53:29.56,0:53:33.02,English,,0,0,0,,And it remains zero until we execute the V 642 | Dialogue: 0,0:53:33.72,0:53:35.60,English,,0,0,0,,And when we finished executing the V 643 | Dialogue: 0,0:53:36.44,0:53:38.38,English,,0,0,0,,The semaphore now is 1 again 644 | Dialogue: 0,0:53:40.10,0:53:42.10,English,,0,0,0,,Okay so if we go through a similar reasoning 645 | Dialogue: 0,0:53:42.90,0:53:48.18,English,,0,0,0,,If we look at the trajectory to get to any point in this state space 646 | Dialogue: 0,0:53:48.22,0:53:52.34,English,,0,0,0,,So let's say this point right here 647 | Dialogue: 0,0:53:54.86,0:54:02.78,English,,0,0,0,,So to get there we could execute thread 1 up to this point finish the L(1) 648 | Dialogue: 0,0:54:04.10,0:54:06.02,English,,0,0,0,,And then execute H(2) 649 | Dialogue: 0,0:54:07.38,0:54:10.68,English,,0,0,0,,And then do the at this point the semaphore is 0 650 | Dialogue: 0,0:54:13.00,0:54:17.04,English,,0,0,0,,And then P decrements the semaphore so now it's -1 651 | Dialogue: 0,0:54:17.86,0:54:20.38,English,,0,0,0,,But that's impossible that can't happen 652 | Dialogue: 0,0:54:21.04,0:54:25.62,English,,0,0,0,,Because P blocks, remember if the semaphore is 0 P blocks 653 | Dialogue: 0,0:54:26.36,0:54:27.28,English,,0,0,0,,It doesn't decrement 654 | Dialogue: 0,0:54:28.40,0:54:35.70,English,,0,0,0,,It okay so the semantics of the P operation prohibits this transition 655 | Dialogue: 0,0:54:36.34,0:54:43.06,English,,0,0,0,,It prohibits this transition to the state where the semaphore is zero to a state where it would be -1 656 | Dialogue: 0,0:54:46.78,0:54:53.82,English,,0,0,0,,And so it creates what we call a forbidden region so these points in the state space 657 | Dialogue: 0,0:54:54.84,0:55:01.20,English,,0,0,0,,Where the semaphore would have a value of -1 are are infeasible 658 | Dialogue: 0,0:55:01.92,0:55:06.30,English,,0,0,0,,That can never be reached by the definition of P and V 659 | Dialogue: 0,0:55:07.92,0:55:13.34,English,,0,0,0,,Ok so this forms a forbidden region around the unsafe region 660 | Dialogue: 0,0:55:13.88,0:55:20.92,English,,0,0,0,,And in doing so provides mutually exclusive access to the critical sections in each thread 661 | Dialogue: 0,0:55:22.04,0:55:22.58,English,,0,0,0,,Okay so if 662 | Dialogue: 0,0:55:25.50,0:55:33.10,English,,0,0,0,,So this is the fundamental reason why P(s) and V(s) can be used to provide mutually exclusive access 663 | Dialogue: 0,0:55:36.96,0:55:37.98,English,,0,0,0,,So many questions on this 664 | Dialogue: 0,0:55:41.20,0:55:43.60,English,,0,0,0,,I explained it so clearly that there's no questions 665 | Dialogue: 0,0:55:48.50,0:55:54.02,English,,0,0,0,,All right good well you get to go...you get to leave early then work on your malloc lab 666 | Dialogue: 0,0:55:54.86,0:55:55.52,English,,0,0,0,,So 667 | Dialogue: 0,0:55:57.56,0:55:58.80,English,,0,0,0,,All right so 668 | Dialogue: 0,0:55:59.64,0:56:04.04,English,,0,0,0,,We'll see you Monday we're going to look at sort of some advanced topics 669 | Dialogue: 0,0:56:04.06,0:56:06.92,English,,0,0,0,,This was like, first introduction to synchronization 670 | Dialogue: 0,0:56:07.36,0:56:12.10,English,,0,0,0,,On Tuesday we'll look at more advanced topics in synchronization in ways 671 | Dialogue: 0,0:56:12.20,0:56:13.96,English,,0,0,0,,Ways that you can use semaphores for to 672 | Dialogue: 0,0:56:14.50,0:56:19.20,English,,0,0,0,,Provide other more interests other interesting kinds of synchronization for your programs 673 | Dialogue: 0,0:56:19.76,0:56:20.54,English,,0,0,0,,Okay 674 | --------------------------------------------------------------------------------