Brief

This website is recording something about my life and technical things. I love computer science and programming~

古诗词日常收藏 - 2

破窑赋 [作者] 吕蒙正 [朝代] 宋代 天有不测风云,人有旦夕祸福。蜈蚣百足,行不及蛇;雄鸡两翼,飞不过鸦。马有千里之程,无骑不能自往;人有冲天之志,非运不能自通。 盖闻:人生在世,富贵不能淫,贫贱不能移。文章盖世,孔子厄于陈邦;武略超群,太公钓于渭水。颜渊命短,殊非凶恶之徒;盗跖年长,岂是善良之辈。尧帝明圣,却生不肖之儿;瞽叟愚顽,反生大孝之子。张良原是布衣,萧何称谓县吏。晏子身无五尺,封作齐国宰相;孔明卧居草庐,能作蜀汉军师。楚霸虽雄,败于乌江自刎;汉王虽弱,竟有万里江山。李广有射虎之威,到老无封;冯唐有乘龙之才,一生不遇。韩信未遇之时,无一日三餐,及至遇行,腰悬三尺玉印,一旦时衰,死于阴人之手。 有先贫而后富,有老壮而少衰。满腹文章,白发竟然不中;才疏学浅,少年及第登科。深院宫娥,运退反为妓妾;风流妓女,时来配作夫人。 青春美女,却招愚蠢之夫;俊秀郎君,反配粗丑之妇。蛟龙未遇,潜水于鱼鳖之间;君子失时,拱手于小人之下。衣服虽破,常存仪礼之容;面带忧愁,每抱怀安之量。时遭不遇,只宜安贫守份;心若不欺,必然扬眉吐气。初贫君子,天然骨骼生成;乍富小人,不脱贫寒肌体。 天不得时,日月无光;地不得时,草木不生;水不得时,风浪不平;人不得时,利运不通。注福注禄,命里已安排定,富贵谁不欲?人若不依根基八字,岂能为卿为相? 吾昔寓居洛阳,朝求僧餐,暮宿破窑,思衣不可遮其体,思食不可济其饥,上人憎,下人厌,人道我贱,非我不弃也。今居朝堂,官至极品,位置三公,身虽鞠躬于一人之下,而列职于千万人之上,有挞百僚之杖,有斩鄙吝之剑,思衣而有罗锦千箱,思食而有珍馐百味,出则壮士执鞭,入则佳人捧觞,上人宠,下人拥。人道我贵,非我之能也,此乃时也、运也、命也。 嗟呼!人生在世,富贵不可尽用,贫贱不可自欺,听由天地循环,周而复始焉。 无题 [作者] 无名 陈事万千似寒霜, 傲雪梅来如故乡. 终南别业 [作者] 王维 [朝代] 唐代 中岁颇好道,晚家南山陲。 兴来每独往,胜事空自知。 行到水穷处,坐看云起时。 偶然值林叟,谈笑无还期。

十二月 8, 2025 · 1 分钟

MIT 6.s081(Operating System)

MIT OS 课程地址: https://pdos.csail.mit.edu/6.S081/2020/schedule.html 在拖沓了许久之后, 终于OS给看完了. 总体来说质量很不错, 设计的lab都很好, 理清了不少底层的概念. 体验 个人觉得OS课程的lab至关重要, 这也是MIT 6.s081做得非常好的点之一, 他们的lab确实做到了由浅入深. 理论知识是围绕xv6来讲解, 同时后期开始讲解OS的一些经典paper, 这些可以让自己对OS的学术领域有一个基本的了解. 然后lab大部分都是修改xv6, 因为xv6的代码非常简洁, 所以修改一般都比较轻松. 难的是OS里面一个很小的细节可能要debug很久. 加深了对所谓并发的理解, 多线程的lab是设计一个用户空间的"线程调度器", 写完之后感觉对多线程/多进程的概念更清晰了, 虽然我觉得这里的多线程更像是协程. 学习了一些经典的技术: copy-on-write, mmap, Read-Copy-Update 看到meltdown的时候有点激动, 原作者是怎么想到这个做法的 ( 看了MIT 6.004之后惊叹数字电路上那么多精妙的设计, 现在看来OS里面也有很多精妙设计, 或者说是体系架构里面. 虽然MIT 6.004学习了页表, 但在OS里面可以看到页表的各种用法, 不得不佩服页表这个发明. 知道了微内核和宏内核的区别 总结 之前觉得一个CPU就是一个通用图灵机, 它的输入也是各种图灵机, 而其中之一就是OS, 而OS本身应该也是一个通用图灵机, 所以本质上OS是通过套娃提高了抽象层次, 简化了操作. 现代OS的几个关键点应该是并发和安全. 对于并发, 常见的说法是多进程和多线程, 但实际上都是一回事, 只不过多线程是共享一个address space. 对于安全, 用页表来实现address space的隔离是个绝妙的idea, 虽然meltdown的出现吓到了不少人, 但这实际上也跟intel自己的micro-architecture实现有关, 好在现在已经可以在硬件层面修复了(不然还是得把用户空间和内核空间分开, 会拉低大概5%的性能). 锁可以解决数据冲突, 但会降低并行性, 过度的使用等于没有并行.

三月 9, 2022 · 1 分钟

Parallel Processing

Parallel Processing 课程地址: https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-004-computation-structures-spring-2017/c21/c21s1/ 本章讲的是各种并行方案. 并行 并行大体上有如下3种: 指令级并行(ILP) 数据级并行(DLP) 线程级并行(TLP) 指令级并行 指令级并行是让流行线的每个阶段尽可能同时执行多条指令. 数据级并行 数据级并行主要是指像向量加法这种计算, 天生就能拆开运算的! 只需要提供多个ALU就行了, 目前主要是由GPU来做. 线程级并行 首先介绍一下阿姆达尔定律: 一个线程就是在一个core上执行的计算任务. Using multiple independent cores to execute a parallel task is called thread-level parallelism (TLP), where each core executes a separate computation “thread”. 不同的Core之间是通过同一个main memory来交换数据(还有更高效的MPI), 而且每个core都有自己的cache. 为了保证数据的一致性, 在cache和内存之间也有一条bus来监测cache的变化和同步. 例如MESI protocal: https://en.wikipedia.org/wiki/MESI_protocol

十二月 16, 2021 · 1 分钟

System-level Communication

System-level Communication 课程地址: https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-004-computation-structures-spring-2017/c20/c20s1/ 本章主要讲的是系统间通信, 按现在来讲就是总线(BUS). 前面讲了很多硬核的物理知识, 证明了单一总线因为传输线反射的问题, 无法做到高频. 后面介绍了PCIe, 原来PCIe是受Network的启发, 也搞了一套点对点的通信协议, 跟网络一样分了几层, 数据也是包装成packet发出去. 跟网络一样, PCIe也可以有多种top, 比如环形, 树形等等.

十二月 16, 2021 · 1 分钟

Concurrency and Synchronization

Concurrency and Synchronization 课程地址: https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-004-computation-structures-spring-2017/c19/c19s1/ 本章主要是讲进程间通信(IPC), 不过是从硬件的角度来看. IPC里面常用的信号量, 其实也只是在共享内存中存入了一个数字, 而所谓的lock, 也只是数量为1的semaphore. 但是如果不同core上的进程同时对同一个内存地址进行写操作的话, 会产生冲突吗? 这个貌似是内存或者总线去解决的, 目前还没找到具体实现, 先mark一下. IPC的一个重要问题是deadlock, 比如进程A和进程B: # 进程A wait(x) wait(y) # 进程B wait(y) wait(x) 当进程A执行完wait(x)后, 进程B被调度, 而且执行了wait(y), 显然这两个进程永远都无法结束. 一个比较直观而且简单的方案是对IPC中需要用到的信号量进行排序, 在进程wait时, 总是先wait顺序在前的信号量.

十二月 15, 2021 · 1 分钟

Devices and Interrupts

Devices and Interrupts 课程地址: https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-004-computation-structures-spring-2017/c18/c18s1/ 本章引入外设, 讲解了round-robin调度算法的优缺点. 首先, “IO阻塞"的本质是什么? 当IO请求没有收到回复时, OS在调度到该进程时还是会继续执行等待IO的指令. 虽然每次调度到正在等待IO的进程也花不了多少条指令, 但还是要切换上下文啥的, 为了提高轮询的效率, 我们可以想办法让这些等待IO的进程不会被调度. 我们可以将进程分为不同的状态, 只有状态为0的进程可以被正常调度. 当进程开始等待IO时, 便用 sleep(id) 来改变进程的状态, 其中 id 相当于这个IO资源的标识符, 比如可以有多个进程都在等待键盘的输入. 当相应的IO时间响应后, 再根据这个id去恢复进程的状态. 加了状态的轮询调度感觉也挺合理的! 那么, 轮询能满足所有的任务吗? 当然是不能! 某些特殊的系统, 例如车载系统, 会有一些特别紧急的中断必须要优先执行, 比如紧急制动啥的. 按我们之前的设计, 中断都是在内核态中执行, 而内核态会禁用中断, 所以当需要紧急制动时, 巧好有一个耗时较长的中断在执行, 可能就会引发悲剧! 像这种每个中断都要及时响应或者在一定时间内执行完成的, 一般称为实时调度. 本章介绍了弱优先级抢占和强优先级抢占两种调度算法. 区别就是当前的中断是否能被高优先级的中断中断 (

十二月 14, 2021 · 1 分钟

Virtualizing the Processor

Virtualizing the Processor 课程地址: https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-004-computation-structures-spring-2017/c17/c17s1/ 本章讲了CPU的"虚拟化", 不过这里的"虚拟化"是指在同一个CPU上执行多个程序, 并且互不干扰, 重点当然就是虚拟内存和MMU啦. 现代CPU都在硬件上实现了内核态和用户态, 所以无法单纯靠软件来实现内核态和用户态的切换, 而是要靠CPU的中断来实现. 当Timer发起一个中断时, 我们调用OS的schedule程序来切换用户程序的上下文, 那么具体需要切换哪些内容呢? 常见的就是所有寄存器的内容, MMU的Context和Page Directory/Page Map的base pointer, 还有其他各种外设的状态等等, 比如该用户程序的输入应该在哪个tty. 这种代码+上下文+所有相关资源的集合便是一个进程(Process). 众所周知, OS提供的底层接口都是在内核态运行, 因为内核态不会受中断的干扰, 所以能够保持调度器一直能正常运行. 但是CPU是禁止程序从用户态直接转移到内核态的, 唯一的办法便是通过中断或者异常. 现代的CPU都运行设置部分中断和异常的Handler, 当用户态程序有中断或异常产生时, 便会跳转到相应的Handler去执行, 而且会无视用户态/内核态的区别. 所以, OS可以指定自己的异常处理Handler, 对于每一个系统调用, 都分配一个illegal-opcode就可以啦!

十二月 13, 2021 · 1 分钟

Virtual Memory

Virtual Memory 课程地址: https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-004-computation-structures-spring-2017/c16/c16s1/ 本章主要讲了从硬盘加载数据到主存的策略, 从而引出了虚拟内存和页表. Extending the memory hierarchy Virtual Memory Page Map Translation look-aside buffer (TLB) Context Summary

十二月 12, 2021 · 1 分钟

Pipelining the Beta

Pipelining the Beta 课程地址: https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-004-computation-structures-spring-2017/c15/c15s1/ 本章主要是讲如何讲前面做的Beta cpu流水线化, 以及如何解决流水线中会遇到的数据冲突/控制逻辑冲突等等. PS: 这章内容是真多 ( 流水线化 冲突 常见的冲突有两种,即数据冲突和控制逻辑冲突. 数据冲突是指当前指令需要的数据暂时还没有写回寄存器或者内存, 控制逻辑冲突是指当要跳转的指令的地址还没计算出来时, 下一个指令的地址应该是多少. 数据冲突 Strategy 1 - Stall Stall就是当指令运行到流水线的某一个阶段时, 如果检测到需要的数据还没有写回寄存器或者内存, 就在这个阶段阻塞住, 而且前面阶段的指令也要同时阻塞住, 阻塞的同时给下一阶段的IR寄存器输出NOP. Strategy 2 - Bypass 虽然每个指令只有在最后的Write Back阶段才会把数据写回寄存器或者内存, 但相关的值在前面的阶段就已经计算出来了, 所以可以直接把这些值bypass到可能需要的地方. 控制逻辑冲突 Stratege 1和2跟前面数据冲突的处理一样, 这里只记录一下第三个做法, 也就是分支预测. 分支预测 Exception and Interruption

十二月 10, 2021 · 1 分钟

Caches and the Memory Hierarchy

Caches and the Memory Hierarchy 课程地址:https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-004-computation-structures-spring-2017/c14/c14s1/ 本章主要讲了SRAM、DRAM、Flash、HDD的原理和现代CPU的缓存架构。 存储设备 PS: 片上的存储设备一般都有bitline和wordline, wordline用来激活指定的存储单元,bitline用来读/写数据。 SRAM SRAM跟寄存器比较像,都是用正反馈是保持电压。 DRAM DRAM是使用电容来保持电压,体积更小,所以容量更大,但访问速度比SRAM慢,而且需要定时刷新存储的数据。 Flash Flash是使用MOSFET来存储数据,在栅极下加了一层绝缘体,讲电子导入绝缘体,然后根据绝缘体的带电大小来决定数据。 Hard Disk 硬盘(这里指机械硬盘)是用磁化来存储数据。 内存系统 在现代CPU的架构中,主存一般是速度相对较慢但是体积更小的DRAM组成。不过CPU不会直接跟主存交换数据,在中间可能会有其他几层SRAM来充当缓存,以降低内存的平均访问时间。 但从编程的角度看,有这样两种选择。一是完全隐藏缓存的细节,这样写程序时便可以把内存当成一个单独的设备使用;二是公开缓存细节,由programmer去决定哪些数据放在缓存,哪些放在主存。 现在除了超算,基本都是选择隐藏缓存的细节。 Cache策略 既然要隐藏缓存的细节,那么需要用硬件或者软件来自动控制哪些数据应该放在缓存,当缓存命中时,直接返回给CPU,未命中时,缓存应当自主去主存读数据然后缓存起来并返回给CPU. 下面来讨论一下具体的缓存策略. 前提 在模拟测试中, 可以发现这样一个事实: Direct-Mapped Full-Associative Set-Associative Policies Replacement Policies Write Policy Summary

十二月 7, 2021 · 1 分钟