自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

我這個人不懂什么CPU,于是我用代碼模擬出了一個

新聞 前端
最近,來自 BBC 的一名資深軟件工程師 Daniel Harper 使用 Go 語言成功模擬出了一個 CPU 的所有功能,并把自己的經(jīng)歷寫成了博客,引起了人們的熱議。

[[266215]]

芯片的設(shè)計到底有多難?想要回答這個問題最好還是先自己實踐一下。最近,來自 BBC 的一名資深軟件工程師 Daniel Harper 使用 Go 語言成功模擬出了一個 CPU 的所有功能,并把自己的經(jīng)歷寫成了博客,引起了人們的熱議。這篇文章也告訴我們:完整地了解計算機的工作原理是多么重要。

Daniel 的經(jīng)歷在社交網(wǎng)絡(luò)上不僅被好奇的群眾點贊,也引發(fā)了大學(xué)芯片相關(guān)課程的學(xué)生和助教們的共鳴。如果你不知道 L1/L2 緩存的意義,認(rèn)為自己沒有搞清楚英特爾、ARM 芯片上著名的 Meltdown、Spectre 漏洞的意義,現(xiàn)在是時候開始學(xué)習(xí)了。

讓我們看看 Daniel 是如何做到模擬 CPU 的:

幾個月前,我實在不理解計算機如何在后臺工作,也不清楚現(xiàn)代計算機的工作原理。之后,我讀了 J. Clark Scott 的書籍《But How Do I Know?》,這本書講述了一臺與非門(NAND gate)8 位計算機,包括寄存器、RAM 以及 CPU、ALU 和 I/O 的位元,于是我想用代碼進(jìn)行模擬。

我對電路學(xué)知識的興趣不大,而這本書只是簡單概述了一些基礎(chǔ)知識,包括接線以及在沒有必備電氣工程知識的情況下位元如何在計算系統(tǒng)中移動。對我而言,從這本書中獲得的知識不多,所以必須親身實踐,并從不可避免的錯誤中吸取經(jīng)驗教訓(xùn),這樣使我能夠有條理地用代碼編寫電路。

  • 相關(guān)成果的 GitHub 地址為:https://github.com/djhworld/simple-computer

這臺簡單的計算機可以用來計算。

示例程序

這是一個相當(dāng)整潔的小東西,CPU 代碼被實現(xiàn)為一個開閉的門,但它奏效了,我已經(jīng)進(jìn)行了測試,以此證明它能夠運行。

該程序操控鍵盤輸入,并將文本呈現(xiàn)給顯示器,其中使用了一套精心制作的字形作為專業(yè)字體,我將其命名為「Daniel Code Pro」。唯一作弊的一點是獲取鍵盤輸入并顯示輸出內(nèi)容,為此我必須通過 GLFW 與外界通信,但剩余部分是模擬電路。

我甚至編寫了一個簡單的匯編程序,這令人大開眼界。這并不是完美的,實際上有點胡扯。但是,我了解到了其他人很多年前已經(jīng)解決了的問題,并認(rèn)為自己的這項工作更好。

為什么要做這個?

我曾看到一個 13 歲的孩子在 Minecraft 中做這項工作,所以等你用電報繼電器制作出一個真正的 CPU 時再來質(zhì)問我吧!

我心中的計算模型還停留在計算機科學(xué)初級教科書的層面,并且驅(qū)動我在 2013 年所編寫的 Gameboy Emulator 的 CPU 與現(xiàn)今計算機運行的 CPU 完全不同。甚至可以說,模擬器只不過是一種狀態(tài)機(state machine),它沒有從邏輯門(logic gate)層面描述 CPU。僅使用 switch 語句即可以實現(xiàn)大多數(shù) CPU 且能夠存儲寄存器狀態(tài)。

我不知道 L1/L2 緩存(cache)和 pipelining 是什么,也完全不確定自己是否理解 Meltdown 和 Spectre 漏洞論文,所以想要更深入地了解這些東西。一些人告訴我,他們正在優(yōu)化代碼以更好地利用 CPU 緩存,而我卻不知道如何驗證真假,只能選擇相信他們。我真的不確定 x86 指令是什么。我不了解人們?nèi)绾文軌驅(qū)⒐ぷ鹘唤o GPU 或 TPU 處理,也不清楚什么是 TPU,更不清楚如何使用這些 SIMD 指令。

但所有這一切都需要具有相關(guān)的基礎(chǔ)知識,所以我只有在閱讀相關(guān)書籍后才能對此有所了解。這意味著我需要回到基礎(chǔ)知識和原理上面,并從一些簡單的程序上手。《But How Do I Know?》一本書中的「Scott 計算機」就很簡單,也是我選擇它的原因。

功能強大的 Scott 計算機!可以運行的!

Scott 計算機是一個附有 256 字節(jié) RAM 的 8 位處理器,并通過 8 位系統(tǒng)總線連接。該計算機擁有 4 個通用寄存器,能夠執(zhí)行 17 個機器指令。一些人搭建了一個很酷的視覺模擬器(visual simulator),無法想象需要花費多長時間才能跟蹤全部的接線狀態(tài)!

組成 Scott CPU 的所有組件圖解

《But How Do I Know?》這本書將帶你從一個不起眼的與非門開始,然后是內(nèi)存和寄存器,最后繼續(xù)對這些組件分層,直到你得出與上述類似的結(jié)果。這本書對相關(guān)內(nèi)容做了非常好的概述,所以我極力推薦大家閱讀,即使你已經(jīng)熟悉了相關(guān)概念。我不建議大家在 Kindle 上閱讀,因為書中的一些圖有時很難在屏幕上放大和辨認(rèn),這是 Kindle 的一大弊端。唯一不同的一點是我將計算機升級到了 16 位,因為僅存儲 ASCII 表的字形就令書中所描述的大多數(shù) 8 位機器無法做到,因此留給有用代碼的空間就不多了。

我的開發(fā)之旅

開發(fā)過程實際上只是閱讀文本、查找圖表、然后嘗試使用通用編程語言代碼(而不是使用為集成電路開發(fā)而設(shè)計的代碼)來翻譯。

之所以用 Go 語言來寫,是因為我對 Go 了解一點。杠精們可能會說,我不信你沒有將時間花在學(xué) VHDL、Verilog 或 LogSim 上,但我那時已經(jīng)編寫好了我的位元、字節(jié)和 NAND,我陷得太深了。也許我接下來會學(xué)那些東西。

從全局來看,大多數(shù)計算機只是傳遞一堆布爾值,所以任何對布爾值友好的語言都可以完成這項工作。

將模式應(yīng)用于這些布爾值能夠幫助程序員獲得其含義,任何人都要做的最大決策是確定系統(tǒng)將使用哪種字節(jié)順序(endianness),并確保所有組件都以正確的順序在總線之間傳遞信息。

這絕對是實現(xiàn)中隱藏的痛點之一。從偏移量上看,我選擇了較小的字節(jié)順序。但在測試 ALU 時,我就遇到麻煩了。我試圖找出為什么出來的數(shù)字是錯誤的。很多很多打印語句都發(fā)生在這個上面。

開發(fā)的確花了一些時間,大約是一兩個月的業(yè)余時間。但一旦成功搭建出 CPU 并用它執(zhí)行 2 + 2 = 5,我還是感到很欣慰。

書中討論了 I/O 特性,設(shè)計了一個簡單的鍵盤和顯示界面,這樣你就可以把東西放進(jìn)機器或拿出來。我給自己設(shè)定了一個目標(biāo),那就是能夠在鍵盤上輸入一些東西,并在顯示器上顯示這些字母。

外設(shè)

在這里,外設(shè)使用的是適配模式,充當(dāng) CPU 和外部世界之間的硬件接口。這里并不難猜,肯定是軟件設(shè)計模式獲取靈感的地方。

I/O 適配器是如何連接到 GLFW 窗口的

通過分離關(guān)注點,使用 GLFW 將鍵盤輸入的內(nèi)容輸出到屏幕是非常簡單的過程。事實上我只是從模擬器中提取了大部分代碼并整形了一下,使用 go 通道作為進(jìn)出機器的信號。

讓它跑起來

這可能是最難的一部分,至少也是最麻煩的。用如此有限的指令集編寫程序集真的很糟糕。使用我編寫的粗糙的匯編程序編寫程序集更糟糕,因為你怪不得別人。

最大的問題在于同時處理這 4 個寄存器并跟蹤它們,將它們作為臨時存儲存儲到內(nèi)存中。在這個過程中,我記得 Gameboy CPU 有一個堆棧指針寄存器,這樣你就可以推送和彈出狀態(tài)。不幸的是,這臺電腦沒有這么奢侈,所以我主要是在定制的基礎(chǔ)上對內(nèi)存里的東西進(jìn)行移進(jìn)移出操作。

我唯一花時間實現(xiàn)的偽指令是 CALL,以幫助調(diào)用函數(shù)。這可以讓你運行一個函數(shù),然后在函數(shù)被調(diào)用后返回到該點。由于沒有堆棧,你只能調(diào)用一層的深度。

由于機器不支持中斷,為獲取鍵盤狀態(tài)等函數(shù),你必須實現(xiàn)糟糕的輪詢代碼。書中的確提到了實現(xiàn)中斷的步驟,但那需要寫更多代碼。

無論如何,我最終編寫出了四個程序,其中多數(shù)程序使用一些共享代碼來繪制字體、獲取鍵盤輸入等。雖然與操作系統(tǒng)還有一定的距離,但它確實讓我意識到一個簡單的操作系統(tǒng)也可能提供一些服務(wù)。

但這其實并不容易,文本編寫程序最棘手的部分是計算出何時轉(zhuǎn)到新行,或當(dāng)你按回車鍵時發(fā)生了什么。

  1. <code>main-getInput:</code> 
  2. <code>    CALL ROUTINE-io-pollKeyboard</code><code>    </code> 
  3. <code><code>    </code>CALL ROUTINE-io-drawFontCharacter</code><code>    </code> 
  4. <code><code>    </code>JMP main-getInput</code> 

上述文本編寫程序的主要循環(huán)。

我也沒有抽出時間來實現(xiàn)退格鍵或其他任何修改鍵。這讓我意識到制作文本編輯器需要做多少工作,這項工作可能是多么乏味。

反思

這個項目對我來說非常有趣,也很有收獲。在用匯編語言編程的過程中,我基本上放棄了底層的 NAND、AND 和 OR 門。我上升到了上面的抽象層。雖然我做的這個 CPU 很簡單,距離電腦里的 CPU 還很遠(yuǎn),但通過這個項目我學(xué)到了很多,如:

  • 位元如何在使用總線的所有組件之間移動

  • 一個簡單的 ALU 是如何工作的

  • 一個簡單的 Fetch-Decode-Execute 循環(huán)是什么樣的

  • 沒有堆棧指針寄存器的機器+堆棧的概念很糟糕

  • 沒有中斷的機器很糟糕

  • 匯編程序是什么、如何工作

  • 外圍設(shè)備如何與一個簡單的 CPU 通信

  • 簡單字體的工作原理和在顯示器上顯示它們的方法

  • 一個簡單的操作系統(tǒng)會是什么樣子

相關(guān)課程

如果你對于芯片的工作原理非常有興趣,先上一些在線課程也是一個好方法。這一 Udacity 免費課程《高性能計算架構(gòu)》源自佐治亞理工:

  • https://cn.udacity.com/course/high-performance-computer-architecture--ud007

原文地址:https://djhworld.github.io/post/2019/05/21/i-dont-know-how-cpus-work-so-i-simulated-one-in-code/

責(zé)任編輯:張燕妮 來源: 機器之心
相關(guān)推薦

2023-11-28 12:00:22

應(yīng)用程序API

2013-08-14 10:23:22

創(chuàng)業(yè)個人創(chuàng)業(yè)互聯(lián)網(wǎng)創(chuàng)業(yè)

2015-12-31 17:54:30

惠普

2022-11-10 09:28:40

框架開發(fā)

2017-07-13 12:33:15

戴爾

2019-12-23 11:03:07

抽象MOVJava

2025-03-06 13:10:32

2018-11-06 21:00:09

Python編程語言人臉識別

2022-03-07 05:53:41

線程CPU代碼

2023-11-02 08:27:29

2013-05-21 09:32:11

ChromebookChrome OS

2015-10-15 09:58:26

HRMMMicroservic微服務(wù)

2017-10-23 12:42:42

2015-09-16 10:35:33

創(chuàng)業(yè)創(chuàng)業(yè)想法

2022-11-03 17:33:40

JavaString 類型

2024-03-13 08:21:53

冒泡排序動畫

2012-09-18 15:35:45

云計算創(chuàng)意大賽微軟

2019-12-02 10:51:11

Redis存儲系統(tǒng)

2023-01-26 00:54:57

2021-11-01 07:21:37

Flink大數(shù)據(jù)SQL
點贊
收藏

51CTO技術(shù)棧公眾號