《小学生也看得懂的红石计算机教程:从零构建自己的红石计算机》

===============================================================
【###======
【#CHAPTER[5]-5.3【SIMD拓展指令集】
【###======
向量指令很有用,所以很多厂商会给自己的CPU添加SIMD多媒体拓展指令集,
以达到向量指令的效果,
SIMD指令的效果比如处理器位数是64位,那么一个SIMD指令可以一次
执行2个32位运算或者4个16位运算,就是这样把64位的运算器
分割成多个低位数的运算器来实现的,孪生物就是对寄存器的高低
段操作支持,比如把64位的寄存器Rn分成上下两个32位的段RL,RH
(RH是高32位,RL是低32位)
比如MOV_RL R1,R2,就可以把R2的RL段挪到R1的RL段中,
R2,R1的RH原封不动.以此类推也可以把寄存器分成更多段,
然后提供更多的高低位操作指令.
(其实英特尔的处理器中,为了支持以前的老指令集,就提供了
高低位支持,可以把32位的寄存器分成两个16位的,
这种兼容性的用途在MC应该不存在.)
更多信息可以百度.
===============================================================

楼主 savenseg  发布于 2019-03-20 21:09:00 +0800 CST  
===============================================================
【###======
【#CHAPTER[6]-6.1【线程与进程】
【###======
这节开始就开始讨论看起来很吊的多处理了,
其实不会多讲因为这个涉及很多复杂的东西(因为一致性地狱,
分布的多处理模型相当恶心),而且MC不大会设计太复杂的多处理,
好吧,如果的确有时候会遇到类似的模型,那就去百度把,别找我.


我们一路讲下来居然现在才讨论线程和进程是什么,着实是个奇迹,
但是有的教材它干脆不提,这就更过分了.


计算机中,
一个程序就是一个进程,
一个进程里面可以有多个线程,
也就是说,进程里面的东西被划分成了n个线程,
当然进程本身还有很多额外只属于它的信息,存在进程表里,
线程可以被创建,也可以被删除,
但是某个进程中创建的线程只属于它本身,
线程创建的办法是通过另一个线程执行某个线程创建指令,
可以让出新创建的线程的内容跟创建者完全一样(复制),
也可以不同(让创建者再设定这个线程的内容),


线程是执行的基本单位,每个线程都有一个程序计数器,
表示线程当前在执行内存中的哪条指令,
但是线程有很多,CPU有一个是怎么回事?
实际上在计算机中线程是轮流执行的,
比如让线程A先跑一下,再让线程B跑一下,
也可以让线程A一直跑直到发出声明让出CPU,
具体方法和机制也有很多.
而切换线程的算法,就被叫做调度算法.
百度"调度算法"


但是你可以看到百度提到的是进程之间的调度,这是因为,
每个进程有n个线程,CPU会先选择一个进程,然后再在进程
里的线程中选一个执行,并且在这个进程内切换一段时间,
然后再换一个进程,在这个进程里又执行并切换一段时间的线程,
就是俄罗斯套娃。


其实这种调度有很多模型,CPU也可以直接在所有
进程的所有线程中轮流切换,具体可以发挥自己的想象力,
因为MC里用不到,所以你感兴趣的话,请参考数目《现代操作系统》,
里面会讲的.


总之,当CPU要执行一个线程的时候,会从它所属的进程中
获得线程表,然后从线程表中获得它的信息,包括它的"程序计数器",
也就是说把线程表里记录的这个线程的程序计数器的值扔到CPU中
的PC里,然后在调度到下一个线程的时候,再把CPU中的PC写回
到线程表中,就实现了线程的切换.


如果线程表存在CPU里,那么CPU就能对所有线程进行调度,
如果存在进程里,那就只能调度这个进程里的线程,
这是两种模型的差异.


所谓超线程,就是牙膏厂整出的一个能在一个CPU上跑多个线程的概念,
超线程就是让一个CPU能同时运行比如两个线程的技术,
具体在CPU内是交替跑的还是真的能并行执行的,这个并不重要.
只要让软件觉得线程在"同时跑",并且我们还真得面临这种同时
执行线程可能产生的问题:同步问题


试想一下,如果两个线程同时在一个单元里写入,然后再读出,
这会是怎样的一个灾难?


同步问题的解决会在后面讨论
===============================================================

楼主 savenseg  发布于 2019-03-20 21:30:00 +0800 CST  
===============================================================
【###======
【#CHAPTER[6]-6.2【多核心处理器与共享内存架构】
【###======
多核心处理器顾名思义,就是一个芯片里集成了多个CPU,
我们把他们称之为CPU_0到CPU_n,
每个CPU都有独立的L1,然后所有CPU都会共享一个L2,
(你也可以让每个CPU有私有的L1,L2,然后让所有CPU共享L3)


CACHE之间的两种映射方法:


直接映射:直接把L2的块映射到L1中,如果这么做,CPU在操作某个
L1中的内存块时,必须得在之后更新它在L2中的副本,
否则L1和L2中内存块的副本就不一致,这在单核处理器中
不是大问题,但是在多处理中就会造成闻风丧胆的"一致性地狱".


互斥映射:L1和L2之间会进行块交换,也就是说L1和L2中,
一个内存块只能存在于L1或者L2中,而不能同时存在,
比如L1满了,这时候想读取内存块7,而内存块7存在于L2中,
那么L1就会在L1中选择一个内存块(比如内存块8)与L2中的
内存块7相互交换,交换后块7跑到了L2里,块8跑到了L1里.


这里我们假定某个多处理器有四个CPU分别是CPU_0到CPU_3,
每个CPU都有私有的CACHE L1并且相互之间共享一个L2,
然后,L2中的内存块会以上面所说的两种办法之一被搬到某个L1中,
那么问题来了,如果CPU0占有了块1,然后CPU1又要操作块1该怎么办?


如果是互斥模型,CPU0得先释放块1,然后CPU1再占有块1。
如果是直接映射,CPU1可以在L2中找到块1,但是如果CPU0占有了
块1后,又修改了它的值,并且并没有及时把修改后的块1写回到
L2中,这就意味着CPU1在L2中找到的块1实际上是CPU0修改前的块1.


事实上可能发生的问题远远不止这些,这种问题叫做缓存一致性问题,
它也有很多不同的解决方法,但可以说都不够漂亮,


一种解决方法是"MSI协议",这个可以百度,
另外还有很多MSI的魔改,比如MESI协议或者MOESI协议,或者其它的办法.
所以请大家百度:
MSI协议,MESI协议,MOESI协议并了解.


共享内存架构:
可以分两种,分别是:
统一内存访问(UMA)
非统一内存访问(NUMA)


具体自己百度就行了.


多处理并不是多核心处理器的专利,如果你把100台计算机用计算机网络
连接起来,然后一起处理任务,也可以叫多处理,
这种叫分布式系统.还有一种多处理架构叫集群,超级计算机也是
一种多处理的系统,它的本质是把很多个高性能处理器连接到一起,
然后把某个并行度很高的任务(比如某个程序有一万个线程)分解
成很多个小任务然后发配给每个CPU处理,
这种把大任务分解成小任务然后发配个多个处理器并行执行
的编程方法叫做多线程编程,或者并发编程.
===============================================================

楼主 savenseg  发布于 2019-03-21 17:50:00 +0800 CST  
===============================================================
【###======
【#CHAPTER[7]-7.1【在GAMETICK上同步的信号时序】
【###======
我们知道,在现实生活中的信号,是连续传导的,
但是MC中不同,MC里的信号是按每gametick进行更新的,
2 gametick = 1 tick
(gametick简称gt,tick简称t)
也就是说红石线从亮到灭,这个过程是离散的,
因为游戏把所有的行为都划分在了以gt为基本段的离散时间里,
比如,在第1gt时,红石线是亮的,但是同时,玩家关闭了
激活红石线的电源拉杆,这样,在下一gt,也就是第2gt时,
红石线会发生一次更新,这时候红石线检测到了电源拉杆已经关闭,
所以会在2gt的时候变暗.每个gt都是原子化的,也就是说,在MC中,
gt就是时间的基本单位,gt不能再被细分.
这种特性导致了一些现实中不存在的性质:
所有的信号在gametick上看来,都是同步的,因为给所有方块状态
更新的事件是每gt发生一次的,所以MC中所有的信号和时间,
都被gt强制同步。
这种性质的优越点是:所有元件和导线的传导延迟都是一直稳定的,
不像现实中,我们很难准确判断一个电线传导电流的速度,
因为它可能受到任何因素导致某次传导花费时间稍微长一些或者短一些,
而MC不存在这种干扰因素,这让我们很容易分析电路的延迟和时序,
并且确定电路是绝对稳定的.


但是BUGJUMP的垃圾优化让我们面临了各种电路特性,
所以有时候电路也不是稳定的,比如在高卡顿的环境下,
电路行为有时候会发生随机的变化.甚至有的时候,
因为电路在同一gt内发生过多次更新,导致MC内存栈溢出.
而导致部分方块的状态没有发生更新,比如说因为太卡,
即使我们拉回了拉杆,某个中继器却还是一直永久保持亮着的,
而旁边的拉杆已经拉回来,这时候我们得在中继器旁边放一个方块,
更新这个方块,才能让他正确熄灭。
所以红石电路依旧存在着不稳定因素,尤其是在高卡顿的大型电路中.
===============================================================

楼主 savenseg  发布于 2019-03-21 23:41:00 +0800 CST  
===============================================================
【###======
【#CHAPTER[7]-7.2【中继器锁与投掷器锁】
【###======
用一个中继器或者比较器侧充能一个中继器,
可以让这个中继器保持当前状态,而不受输入的影响.
如果是中继器充能它,可以看到中继器上会出现一条基岩,
我们称这种状态的中继器为中继器锁(它对应的一个标签是locked),
但是比较器测充能中继器后,即使它也会锁住状态,但是并不会
在上面出现一个中继器条,不过我们还是称他为中继器锁。
这样中继器加上对中继器侧充能的中继器或者比较器,
我们就得到了一个简单的D触发器,结构非常简单,性能也很高.


投掷器被充能后,就一直保持着被充能状态,这时候其它信号对他
充能不会激活投掷器发射物品,利用这种性质,我们让投掷器的发射头
对准一个漏斗,然后漏斗也对着这个投掷器漏东西,
这时候,如果我们激活漏斗锁住漏斗并且激活投掷器,
就保存了这个投掷器和漏斗的状态,把它熄灭再亮起,就能把投掷器
和漏斗的状态更新为输入的信号,我们通过比较器检测漏斗里是否
有物品来得到这个D触发器的输出.


用来参考,使用投掷器D触发器的一个例子:
https://tieba.baidu.com/p/6072929751?pid=124664830681&cid=0&red_tag=0959784077#124664830681
===============================================================

楼主 savenseg  发布于 2019-03-21 23:41:00 +0800 CST  
===============================================================
【###======
【#CHAPTER[7]-7.3【线或逻辑】
【###======
在现实中我们不能对一个导线同时输入高低电平(也就是1和0),否则电路
会出错,但是在MC中我们给一给红石线输入1和0,结果会是1,
结果,只要对红石线的输入有一个是1,那么红石线的状态就是1,
(如果考虑信号强度,那么这个红石线的状态就是输入的最强的信号强度)
这相当于给每个输入做了一个或运算,
我们称这种性质为线或逻辑.
利用这种性质,结合半砖的单向传导性质,
可以做出无延迟的或逻辑门.
===============================================================

楼主 savenseg  发布于 2019-03-21 23:44:00 +0800 CST  
===============================================================
【###======
【#CHAPTER[7]-7.4【TICK级流水化执行与串行单元内流水化执行】
【###======
我们之前提到,MC的时间基本单位是gametick,
利用这种性质,我们可以开发TICK级别的流水化执行,
我们按照一定频率,比如2ticks发射一次信号,给一个与门发射信号,
它就会按照2ticks一次的频率输出运算结果,
这样,电路运算频率就提高到了2ticks/次,
但是要让电路能支持TICK级的流水化,还有几个必须满足的条件:


电路必须能被分成A->B->C->.....->G,这样n个部分,并且
第n个部分的输出只会接到第n+1个部分的输入上.
然后,这个电路的最大处理频率,就取决于这n个部分中,
频率最低的那个部分的频率.
比如某个电路被分成3个部分,第一个和第二个部分都可以按照
每tick处理一个数据的频率工作,但是第三个部分就只能每2ticks
处理一个数据,显然,这个电路的最高频率只能是2ticks.
这么做要求我们能够尽量分解电路中的部分,把处理频率低的部分,
分解成多个处理频率高的部分.这样就能提高整个电路的处理频率.


想想一个加法器,有两个输入A,B一个输出C,
我们把C接到A上,就形成了一个累加器,这时候每给B输入一次数据,
加法器中的值都会被+1.但是如果连续给这个累加器输入数据呢?
比如按照2ticks/次频率输入数据,
我们假设加法器总延迟8ticks,然后它的最高处理频率是2ticks,
并且C和A之间的链接没有延迟.


那么,我们就可以知道.如果我们按照2ticks/次的频率给加法器
连续输入四次数据,那么这四个数据会分别占在加法器总延迟长度的
第1,2t和第3,4t和第5,6t和第7,8t.
也就是每2t占有一个单位,我们把这四个数据叫做A,B,C,D.
然后把加法器=第1,2t的部分称为P1,第3,4t的部分称为P2,
第5,6t的部分称为P3,第7,8t的部分称为P4.


这样,我们给加法器连续输入4个2ticks长度的信号,并且信号之间
没有延迟的话.A,B,C,D应该分别处于P1,P2,P3,P4.
但是如果再经过2t,每个数据都会前进,
A跑到了P2,B跑到了P3,C跑到了P4,D跑到了P1.
(D跑到P1的原因是我们把C和B连起来了)
这样,这个加法器就可以存储四个数A,B,C,D.
然后,每过2t,就会有一个数跑到B端口,然后再过2t,这个数
会从B端口再次进入加法器,然后这个数后面的那个数进入B端口,
以此类推的,就像衔尾蛇.


这样,如果我们再给A端输入数据,他会加到A,B,C,D中的一个。
如果我们连续输入四个数据,他们就会分别加到ABCD中.
然后又因为MC的同步性,我们可以计算时序,判断当前处于B端口
的是谁,这样,假如我们又要输入一个序列E,F,G,H,我们想要达到的
效果是把加法器里的ABCD变成A+E,B+F,C+G,D+H.
所以我们得在ABCD中的A到达端口B的时候,开始输入序列EFGH.
这样就可以完成A+E,B+F,C+G,D+H.


这种TICK级的流水化技术可以把一个运算元件当作n个用,
具有相当高的效率.


我们也可以把它理解为运算器中存在着n个线程,
并且线程按照电路的最高频率不停轮流切换运行.


===============================================================

楼主 savenseg  发布于 2019-03-21 23:44:00 +0800 CST  
===============================================================
【###======
【#CHAPTER[7]-7.5【活塞进位链与CarryCancelChain】
【###======
在MC中,有办法设计出空间复杂度为o(n)的超前进位加法器.
实现这种电路的办法有两种:
用活塞进位链,或者用cca进位链.
两者都可以实现超前进位,区别是cca用了比较器,而活塞进位
链用了活塞.
活塞加法器的相关链接:
https://tieba.baidu.com/p/4887366249?red_tag=2927863550
CCA加法器的相关链接:
https://tieba.baidu.com/p/5152935985?red_tag=2882826465


可供参考,但是实际上现在两种加法器都有相当优秀的设计,
分别都达到了3t的延迟并且有超小的体积.
两种加法器的3t设计都来自于Nikkeru.
===============================================================

楼主 savenseg  发布于 2019-03-21 23:51:00 +0800 CST  
===============================================================
【###======
【#CHAPTER[7]-7.6【模红技术】
【###======
模红可以分强摸电路和弱摸电路,
弱摸电路仅使用0到15的红石信号强度进行强度运算,
而强摸电路可以使用0到2^31-1的红石信号进行强度运算.


不过,经过ARCSINE的研究后,发现强模下限实际上是-(2^31-1),
但是因为负强度只能被比较器检测而不能被传导,也就是说
只有接了电源的比较器才能输出负强度信号,比较器不能从
一个输出为负的比较器中继承信号强度,但是如果对一个正端输入
非0的比较器两侧同时输入负信号,那么可以增强这个比较器的输出.
因为这些特性,负强度信号难以实际运用于电路中,所以一般不考虑
负强度信号.


强摸可以利用比较器减法模式完成0到2^31-1范围内的减法,
利用公式:
O-(O-A-B),O=2^31-1
可以让A,B两个强摸信号相加.


强模信号必须被转化为弱摸,才能被其它输出设备正确识别,
因为比较器输出到别的原件上要么是1要么是0,
在红石线上则是0到15.
强摸转任意进制的算法很简单,
假设强摸信号的范围是0到127,要把它转化成二进制.
我们把这个信号的强度称为s,这个算法的过程是这样的:


如果s大于64,则s减去64,并且称s对应的二进制数第7位为1
否则称s对应的二进制数第7位为0,并且直接进行下一步.


如果s大于32,则s减去32,并且称s对应的二进制数第6位为1
否则称s对应的二进制数第6位为0,并且直接进行下一步.


如果s大于16,则s减去16,并且称s对应的二进制数第5位为1
否则称s对应的二进制数第5位为0,并且直接进行下一步.


如果s大于8,则s减去8,并且称s对应的二进制数第4位为1
否则称s对应的二进制数第4位为0,并且直接进行下一步.


如果s大于4,则s减去4,并且称s对应的二进制数第3位为1
否则称s对应的二进制数第3位为0,并且直接进行下一步.


如果s大于2,则s减去2,并且称s对应的二进制数第2位为1
否则称s对应的二进制数第2位为0,并且直接进行下一步.


如果s大于1,则s减去1,并且称s对应的二进制数第1位为1
否则称s对应的二进制数第1位为0,并且直接进行下一步.


可以看到相当的简单粗暴,并且一直遵循着如果s大于n则减去n,
否则跳到下一步这个步骤.
类似的可以把这个算法推广到任意进制上.
===============================================================

楼主 savenseg  发布于 2019-03-22 00:02:00 +0800 CST  
===============================================================
【###======
【#CHAPTER[7]-7.7【无代价的布线交叉技巧】
【###======





看图明白
===============================================================

楼主 savenseg  发布于 2019-03-22 00:04:00 +0800 CST  
===============================================================
【###======
【#CHAPTER[7]-7.8【传导均匀的集线器,无延迟技术与其缺陷】
【###======
MC里的一根线的延迟是显著的,如果我们把中继器接到其中的一段上,
检测这段上是否有无信号.我们就可以判断在此时在这根线上发射
信号是否会跟其他信号有碰撞(合并)的风险.
于是我们便可以直接判断目前是否可以向数据线上发布数据.


无延迟技术不多说了,大家估计都熟悉,
它的运行不需要任何延迟,但是它有很多缺陷,所以我不建议
玩家随意使用无延迟的技术:


无延迟会造成单个gt内的大量更新,很容易造成游戏栈溢出,
导致某些更新事件未能正确发生而导致了电路的异常行为.


大多数无延迟元件都有比较高的元件恢复延迟,也就是说,
我们使用它了后,要等一段时间才能再次使用它.
这样反而实际降低了电路的处理频率,降低了电路性能.
===============================================================

楼主 savenseg  发布于 2019-03-22 00:12:00 +0800 CST  
===============================================================
【###======
【#CHAPTER[7]-7.9【生物栈,基于容器的ROM,流存储器,一种摆脱随机跳转的段式程序非虚拟化模型】
【###======
生物栈利用了实体可以无限堆叠的性质,把所有实体都堆叠
到一个位置上,然后用活塞把生物压入/提出,研究发现活塞实际上
会按照先进先出的顺序压入/提出生物,所以我们就得到了一个
理论上无限容量的栈.


我们可以在箱子里放东西,然后让漏斗不断导出物品,
然后再把物品塞回去,放到原来的地方,这样我们用
不可堆叠物品代表1,可堆叠物品代表0,就可以让漏斗在导出物品
的时候,根据导出物品是否属于不可堆叠物品(如果是,比较器会在
漏斗上检测输出信号强度3,否则为1)
然后,如果我们再把箱子里的所有东西导出来,再让漏斗
按照顺序往箱子里放可堆叠或不可堆叠物品,我们就可以修改这个容器
的内容.


我们可以弄一个很长的中继器环和比较器环,然后让里面的信号循环
流动,这有点类似TICK级流水化技术,本质上是一样的.


对于上面提到的三种存储器,我们发现这些存储器如果是顺序提取数据,
效率是非常高的,并且体积很小,但是如果要进行随机访问,
那就得接受相当严重的延迟代价.


所以这里就研究出了一种摆脱随机跳转的段式程序非虚拟化模型,
消除了大部分的随机访问请求,让这种存储器也能很好的运用在
计算机中:
https://tieba.baidu.com/p/6067716611?pid=124582514896&cid=0&red_tag=0659496760#124582514896
===============================================================

楼主 savenseg  发布于 2019-03-22 00:20:00 +0800 CST  
===============================================================
【###======
【#CHAPTER[7]-7.10【地图屏幕】
【###======
MC里存在着名为地图的这种神奇东西,并且只要拿在手上,
就会不断更新地图.
我们可以通过改变地形,来实现地图屏幕.并且这种屏幕可以支持
多种色彩,一种以4*4为一个像素的地图显示器可以改变地形,
让地图上的某个像素显示15种颜色中指定的一种
===============================================================

楼主 savenseg  发布于 2019-03-22 00:22:00 +0800 CST  
有人吗

楼主 savenseg  发布于 2019-03-22 09:24:00 +0800 CST  
顺便附上A53和I7处理器的架构和介绍,可以作为实际设计的参考,
来自computerarchitectureaquantitativeapproach6th.











楼主 savenseg  发布于 2019-03-22 20:01:00 +0800 CST  
有人ma

楼主 savenseg  发布于 2019-03-22 20:30:00 +0800 CST  
推荐一下一个红石服务器,服务器里面有大量的数电模块可以引用
《open redstone engineer》百度就可以看到他们的官网

楼主 savenseg  发布于 2019-05-27 09:02:00 +0800 CST  

楼主:savenseg

字数:34097

发表时间:2019-03-16 19:01:00 +0800 CST

更新时间:2019-09-05 16:17:56 +0800 CST

评论数:350条评论

帖子来源:百度贴吧  访问原帖

 

热门帖子

随机列表

大家在看