Aurora_漪的博客

假如有人抓到别人在穿越麦田

今天久违的状态还可以。总算是有点心思学数学了。

之前一直不想学,可能是想给自己找个台阶下吧,毕竟学了但学不好就很丢人,不学是不是一种开摆的逃亡。

如果真有一个地方不用为了考试为了自证地去学习,我大概还是会去打游戏看番吧。就像这几天一样。不知道还有什么喜欢的事情了。北京越来越冷了,过几天就要下雪了。

cs61c 完结🎉

前天总算是看完了 cs61c,关于并发的部分看的很潦草,虽然但是 cs61c 本身讲的也不是很清楚。开始整理 cs61c 的笔记。艹为什么每次想做点事情总会告诉自己这样就是面子工程形式主义浪费时间呢。

可能我不太喜欢产出吧,学习习惯不好?无所谓的。

数学😶‍🌫️

说是今天学数学其实还不是在还之前的债,线代复习了过去的 ppt,微积分看了之前的课(虽然听不懂一点),感觉微积分和线代已经一点不熟悉了。

离散数学也很难的,以后是不是都应该交给 gemini 帮我学习。不过有一说一,ai 帮忙确实学的好一点,感觉上是听懂了什么。今早做了个梦让 g 指导赛博解梦分析的头头是道,很给情绪价值。

为什么大家都那么卷啊。我只会嘴上说着自己不卷不卷其实还是想好好学啊,但学也不会学,只好说自己不想卷摆出来我轻松我自由我没有心理负担我视野开阔我心胸宽广的样子。孰对孰错也没什么意思不是你能不能别学了啊。

我到底想不想要自由轻松的生活呢,但这样的日子也不是卷来卷去就能保证的。我想去送外卖,但真让我送外卖可能我也就不想了。

芳华🎞️

昨天看了芳华作为打一天游戏的惩罚(一代人有一代人的芳华和过去。里面的隐喻我也不愿多提,只是人与人的悲欢各不相同,社会沧桑巨变冷酷无情,芳华渐老抗拒着温情又渴望着真。很深度的电影,能看懂多少不知道。这部电影是最后一节音乐课上看的,高二下学期。有点想上海的同学。他们那入秋了吧。我还以为大学能像高三那样时不时去看看鸟呢。

多矫情啊。文字水平真是拉了。就这样吧夜也深了。今天丰富了图库,针不戳。

Cache 缓存

为了解决内存空间大但访问慢的问题,设置缓存作为中间站。cpu 与 cache 的交流比内存要快的多。

缓存和内存都是随机访问存储器件,但是缓存是 SRAM,通过晶体管实现,不需要通电保持数据,每个比特需要大量晶体管来保持所以价格巨贵。相比之下内存是 DRAM,电容实现所以会不断发生漏电,需要隔一段时间通个电来刷新。简单而言是这样。

第一种:Direct-Mapped Cache 直接映射缓存

T - I-O:实际上是把内存地址分块,解决内存大缓存小,多对一映射的空间问题而存在。I 是 index,对应内存地址中间位,标记数据去往 cache 的哪一行,也就是哪一个块。o 是 offset 偏移量,因为缓存和内存之间是以块 Block 为交流单位,所以一个块中会对应多个存储位置。offset 确定了存放在哪个位置。缓存 T 是 tag,对应内存地址的高位,作为地址的标志符,验证所取到的内容是不是需要的。对于直接映射缓存,有:
$I = row = block/blocksize, O = blocksize$

课上的比喻很有意思:Baggage claim(行李领取处)。虽然所有飞机的行李都在同一个转盘(Index),但你需要通过行李牌(Tag)来区分哪个箱子是你的。

具体实现中,直接映射缓存是多对一的映射结构,即 index 相同的块对应缓存的同一位置,所以当现在需要检索的内存地址 tag 和 index 对应缓存的 tag 不一样时需要踢掉原来的。这也催生了 valid 位,有效位,用来标识缓存的这个 block 是否可用,是不是垃圾(和垃圾比 tag 有什么用),确保获得的内容准确性。

电路图看的明白一点。

Hit and Miss:

就是缓存命中和缓存未命中,Hit 就是所需地址就在缓存中且有效。缓存未命中则分很多种,compulsory miss 描述一个从未进入过缓存的块必然会发生的一次未命中,比如程序刚刚启动需要加载一车地址,而这些地址都不在缓存中。conflict miss 指的是除了 compulsory 之外,发生冲突的那些未命中。比如两个 tag 不同的块加载到同一个 index 下就会发生踢人事件。capacity miss 描述由缓存本身容量决定,不得不踢人,而不一定是发生矛盾(其实没有矛盾哪需要踢人。。。只是如果缓存大一点就不会发生矛盾)这种和直接映射缓存没关系了。还有一种在后面介绍。然后就有了命中率,AMAT 公式那些东西可以描述缓存的性能。

Write-back and Write-through:

写回和写穿透。区别在于写穿透是每次 cpu 修改了数据,会在缓存和内存都进行修改。这样做确保了内存里的数据每时每刻都是新的,但是对内存操作实在太慢,所以有了写回模式,即 cpu 只对缓存进行修改,暂时不动内存,而是把缓存中修改的那一块的脏位 dirty-bit 设置成 1,标识这个位置已经修改过了。那什么时候写回,这发生在脏块被踢走 eviction 的时候(这样就不得不改内存了吧)以及强制刷新。性能确实极大提升,但是带来缓存不一致的问题会导致多核心操纵内存时卡 bug,留到后面。不过,如果写的时候地址不在缓存中怎么办,还得分两种:Write-allocate 和 No-Write-allocate,写分配是从内存读数据到缓存再修改缓存,非写分配则绕过缓存直接改内存,这会让缓存中没有这个地址对应的块。还有个 Write-around 写绕,就是只写内存,挺捞的就不提了。

时间相关性和空间相关性:

缓存最精妙的思想,因为当我们读到一个地址,很有可能我们还会再用相同的地址;很有可能我们会用相邻的地址。既然有一个很可能下次还会再用的地址,那为什么不找个地方存起来,这就是缓存了啦;为了保证不用从内存中再拿相邻地址里的东西,就一次性拉一车地址过来,这就是 cache 是以 block 为单位的原因。缓存的性能提升都和这两个思想有关。

第二种:Fully-Associative Cache 全相联缓存

直接映射缓存不是经常发生踢人事件嘛,那就让 block 们之间不要冲突就好了,来一个 block 占一个位置,这样每个 block 都有位置可占,不会发生 conflict miss 了。

这样一来就没有 index 区段了(因为没有固定的映射关系了),也就是说 any block can go anywhere in the cache, and must compare with all tags in entire cache to see if data is there。写入时随便放,读取时并行检查每一行

这样当然好,前提是造起来不贵,当然没有这个前提。因为要给每行都做一个比较器,这个非常昂贵,所以全相联缓存基本只用在 TLB 上。

第三种:N-Way-Set-Associative-Cache 组相联缓存

那就折中一下,依然做映射,但是原本(直接映射)是一个 index 只能容纳一个块,现在扩充一下容错,让一个 index 容纳两个或更多的块,这样发生 conflict miss 就大大减少。同时,因为只要对每条路做比较器,硬件成本也可以接受了。

现在 index 指向的是一个 set 组,一个 set 里有多个 block。在这张模式图中看到相同的组用同种颜色标出了,这样相同 index 就能容错了。不过,在 block 总数相同的情况下这样分组到底有什么用,在平均随机的内存访问下确实性能和直接映射是基本相差不大的,因为这种情况最终大家都会被塞满,然后不断踢来踢去。不过现实中绝大部分都是具有空间相关性的访问。这样直接映射会有很多空位不能坐的情况,比如来回访问 AB 两个地址,直接访问就会打起乒乓,但组相联就可以把两个人一块存下来。

我很喜欢这张图。很明显的突出了组,块,路是什么。set 就是行,block 就是一个长方条,way 是大坨大坨垒起来的四个大块。同时体现了一个电路的常见模式:不管控制信号是什么先直接给出数据,这样省电路,也表现了 hit 所需的条件:有一个 tag 击中了而且不是垃圾位,这样依靠这个 tag 的信号控制选择器选择 data。

Block Tradeoff:

想到直接映射总是 conflict,那为什么不把每个 block 里的字节数做大一点,这样就能多容纳一点地址了啦,就减少 conflict 了啦。的确在一开始命中率确实会提升,利用了空间相关性,访问大数组的时候一个 block 就能存很多,不用开一个新 block 存了多好啊。但是太大的话,相同 block 总数情况下必然导致 index 减少(宽度增加行数减少),这会使得命中率降低,很容易打乒乓。而且这样未命中惩罚也很大,每次要搬一大堆数据从内存,说不定新开搬来的数据完全用不到,还会被新数据挤走,这就很捞。

也就是说要对 block 的大小做权衡。

最后讲到踢地址的几种方式,LRU,FIFO,RAND 等,以及多级缓存。多级架构实在是经典。为了弥补一个缓存的低效,用第二级缓存去保证第一级缓存 miss 了可以从第二级找数据用,免得去内存找。第二级缓存拥有第一级的所有数据,比第一级容量大但速度慢,相当于给第一级打个补丁接漏水的属于是。

写好累放个图奖励一下

有一说一真不知道今天应该写什么。虽然是第一篇正文博客。

数学😒

牛魔真的不想学一点。线代完全听不明白在干什么(好吧今天没有线代),今天上的是离散数学。也很恶心好嘛。各种关系搞来搞去,值得一提的是这些关系可以描述图,然后就讲到 Warshall 算法。

搭网站😎

工信部短信通知过了,现在就等十几二十天终审备案就能拿到域名了。一个自己的域名。不过花在搞博客的时间的确太长了,代码全问 ai 还是玩了很长时间。有点意思但不多,可能是生活实在枯燥有乐子就能乐很久。

CS61C

讲的缓存,课程总结过几天再说今天都熄灯了。Dan 讲的比较抽象,还是 Bora 讲的适合中国宝宝体质。这两天没看课都有点忘了。

力扣

不知道刷算法题有什么用。对数学快要不及格的我来说还在做这些有的没的。逃避呗。

总之今天做了几道红题,虽然有道题是在提示 + ai debug 完成的,还不错,但是时间花的太长了,一道题能想一个小时,哪怕是到红题是不是也有点浪费时间。

就这样吧。反正每天都这样。

Hello World!

无数的人用无数种语言写过 hello_world。 —Woziji Shuode

在摆弄了一整天 g 指导之后终于基本搭建好博客。Hexo + NexT 还是挺好看的捏。

虽然这么玩来玩去很浪费时间,虽然线代作业还有 6 个小时就截止了,虽然还有一大堆目标没完成。

最有成就感的还是用自己的手在互联网的一个角落里写下了你好,世界!

很好!这就回去赶作业吧!

Gridea 和 Hexo

初中的时候用 gridea 做过个人博客,发了几篇算法相关的博客就懒得写了了。当时也是发在 gitpage 上(btw 当时 github 还没被墙)
感觉 Gridea 确实很好用,生成的界面也十分美观干净,所以现在想着建站的时候也去搜了一下 Gridea
不过好像已经不是开源的项目了,开源仓库也年久失修,最新版是 22 年发的,和我最早的博客一样没了下文啊
然后用 hexo
全命令行当然也没什么大不了,不过确实不太直观。然后就是各种 debug
NexT 原生界面也就比较简洁而已,我想加点花活还得问 g 指导,这个主题扩展性比较一般
然后就出意外,出了意外再问 g 指导,修好了这个再修那个。一方面是水平问题,不会前端的东西,另一方面基本上算是把 NexT 的 css 重构了一遍
想美化一下 NexT 真不容易,就这样玩了一整天 hh

坚持

不管用什么编辑器,博客模板,最后还是得坚持写。萌生这个想法主要是看网课看太快结果忘的也挺快,记录下来算是给将来的一点积蓄
Just go with it.