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

你覺得用不上的位運(yùn)算里,隱藏著 CPU 實(shí)現(xiàn)的秘密

商務(wù)辦公
我們學(xué) JS 的時(shí)候都會(huì)了解下位運(yùn)算,在 React、Typescript 等源碼中也頻繁見到位運(yùn)算的蹤影,但在業(yè)務(wù)代碼中從來不會(huì)這么寫,它好像離我們很遙遠(yuǎn)。

[[428142]]

本文轉(zhuǎn)載自微信公眾號(hào)「神光的編程秘籍」,作者神說要有光zxg 。轉(zhuǎn)載本文請(qǐng)聯(lián)系神光的編程秘籍公眾號(hào)。

我們學(xué) JS 的時(shí)候都會(huì)了解下位運(yùn)算,在 React、Typescript 等源碼中也頻繁見到位運(yùn)算的蹤影,但在業(yè)務(wù)代碼中從來不會(huì)這么寫,它好像離我們很遙遠(yuǎn)。

但是位運(yùn)算真的遙遠(yuǎn)么?

其實(shí)并不是。你寫的所有代碼最終都會(huì)轉(zhuǎn)為位運(yùn)算,位運(yùn)算里隱藏著 CPU 實(shí)現(xiàn)的秘密。

下面我們就來談一下位運(yùn)算與 CPU 的關(guān)系以及位運(yùn)算在代碼中的應(yīng)用。

從晶體管造 CPU

晶體管

先來了解下晶體管。

下面這個(gè)是三極管,它就是一種晶體管,特性是從一端通電,另外兩端的電流就可以通過,不通電,另外兩端的電流就不能通過。

這特性不就是一個(gè)開關(guān)么?

它和下面這個(gè)東西差不多,只不過不需要手動(dòng)開關(guān),而是通過通電來控制開關(guān)。

開和關(guān),就是 1 和 0。計(jì)算機(jī)世界的組成單元 1 和 0 就是這么實(shí)現(xiàn)的。

邏輯電路

有了 01 就可以構(gòu)成邏輯電路了,也就是與門、或門、非門、異或門等構(gòu)成的電路。

它們的電路符號(hào)是這樣的:

與門:

或門:

非門:

異或門:

它們?cè)?JS 中怎么表示呢?

與 &

或 |

非 ~

異或 ^

它們就是通過三極管構(gòu)成的邏輯電路的基本單元,能夠?qū)崿F(xiàn)基于 0 1 的邏輯。

什么邏輯呢?

1 & 0 為 0

1 | 0 為 1

~1 為 0

0 ^ 0 為 0

與或非大家比較熟悉了,這里講一下異或:

異或是相同為 0,不相同為 1,也就是一個(gè) 0 和一個(gè) 1 才會(huì)得出 1,否則為 0

運(yùn)算器

我們了解了位運(yùn)算是什么,邏輯電路是什么,那有了邏輯電路能做什么呢?

能做的可多了,CPU 不就是一個(gè)大邏輯電路么,它就是建立在位運(yùn)算基礎(chǔ)上的。

比如我們實(shí)現(xiàn)下 ALU 運(yùn)算器:

首先實(shí)現(xiàn)加法:

加法在二進(jìn)制里面就是異或,不信我們來試一下:

1 和 0, 0 和 1 想加是 1 ,而 0 和 0,1 和 1 相加都為 0,這不就是異或么。

當(dāng)然,還要處理進(jìn)位,進(jìn)位可以通過與運(yùn)算得到,比如上面那四個(gè),只有 1 和 1 相與才為 1,否則都為0,這就算出了進(jìn)位。

能夠按位相加和進(jìn)位,就能實(shí)現(xiàn)加法器。

  1. function add(a, b) { 
  2.     let sum = a; 
  3.     let carry = b; 
  4.  
  5.     let temp
  6.     while(carry != 0) { 
  7.         temp = sum
  8.         sum = temp ^ carry; 
  9.         carry = (temp & carry) << 1; 
  10.     } 
  11.  
  12.     return sum

測(cè)試一下加法器:

注意,上面的與和異或不都有邏輯電路么,那用電路實(shí)現(xiàn)上面這段代碼不就是硬件實(shí)現(xiàn)的加法器么?

有了加法,很容易就可以得到減法器:

  1. function subtract(a, b) { 
  2.     var substrahend= add(~b, 1) 
  3.     var sub= add(a, substrahend) 
  4.  
  5.     return sub 

把被減數(shù)變?yōu)橄喾磾?shù),再和被減數(shù)相加不就是減法么?

至于這里為什么是取反加一,就涉及到原碼反碼補(bǔ)碼了,

因?yàn)?1 對(duì)應(yīng) -1,而 0 呢?并沒有 -0,所以就少了一位。所以要加一才能對(duì)上,也就是補(bǔ)碼的“補(bǔ)”的意思,補(bǔ)上沒有 -0 導(dǎo)致的缺少的那個(gè)編碼。

實(shí)現(xiàn)了加法器、減法器之后,乘法和除法也就有了,因?yàn)槌朔ú痪褪嵌鄠€(gè)加么?除法不就是多個(gè)減么?

就這樣,我們從位運(yùn)算實(shí)現(xiàn)了加減乘除。

對(duì)應(yīng)到硬件上呢?就是我們通過三極管實(shí)現(xiàn)了邏輯電路,然后又用邏輯電路實(shí)現(xiàn)了加減乘除。

CPU

上面那個(gè)東西在 CPU 里叫做 ALU,算術(shù)邏輯單元,可以做邏輯運(yùn)算、算術(shù)運(yùn)算。

而且基于三極管還可以做到存儲(chǔ) 0 1 等目的,構(gòu)成寄存器。

有了這些東西我們就可以實(shí)現(xiàn)一個(gè) CPU。

神不神奇,通過晶體管和位運(yùn)算,我們就能把 CPU 造出來,雖然也就需要數(shù)億個(gè)晶體管吧。

當(dāng)然,我們只了解這些意義不大,還要了解位運(yùn)算的應(yīng)用。

位運(yùn)算的應(yīng)用

文件系統(tǒng)

看過我前面一篇文件系統(tǒng)實(shí)現(xiàn)原理文章的小伙伴會(huì)知道,硬盤會(huì)劃分為數(shù)據(jù)塊來使用,一個(gè)文件就是由多個(gè)數(shù)據(jù)塊構(gòu)成的:

文件會(huì)通過一個(gè)叫 inode 的結(jié)構(gòu)來記錄用到了哪幾個(gè)數(shù)據(jù)塊:

那我想存文件的時(shí)候,怎么知道哪些塊可用呢?

一個(gè)塊只有空閑和非空閑兩種狀態(tài),一個(gè)位 0 和 1 就可以保存,所以會(huì)用位圖這種結(jié)構(gòu)來記錄。

比如當(dāng)我存儲(chǔ)圖片占用了 2 和 4 號(hào)塊的時(shí)候,就會(huì)把位圖的對(duì)應(yīng)位置置為 1,否則為 0。那么當(dāng)我需要存儲(chǔ)文件的時(shí)候,從位圖中查一下就知道哪些數(shù)據(jù)塊可用了。

通過位圖記錄狀態(tài),通過位運(yùn)算來判斷狀態(tài)。占用空間小,運(yùn)算效率高。

操作系統(tǒng)級(jí)別都是這么干的,很多追求性能的庫(kù)也都這么干。

React 和 Typescript

在 React 和 Typescript 等源碼中,經(jīng)常會(huì)見到一個(gè)叫 flags 的東西,flags 就和我上面說的位圖差不多,通過一個(gè)位標(biāo)識(shí)一個(gè)狀態(tài)。

比如下面這段 React 的源碼:

這就是判斷了 這個(gè) fiberNode 是否有 Placement 或者 Hydrating 的狀態(tài),如果有就 xxx。

再來看 Typescript 的源碼中的這段代碼:

~ 是取相反狀態(tài),再 & 就是判斷是否沒有這個(gè)狀態(tài),然后通過 | 設(shè)置到 flags 里面,意思就是這個(gè) flags 加上沒有 xx 狀態(tài)的標(biāo)識(shí)。

業(yè)務(wù)代碼

操作系統(tǒng)、優(yōu)秀的庫(kù)中都用到了位運(yùn)算,因?yàn)樗鼈冃阅芨撸苯佑秒娐匪?,存?chǔ)空間也小,那是不是我們代碼中可以用呢?

可以是可以,但是業(yè)務(wù)代碼追求的更多是可維護(hù)性,如果你寫出上面那種 typescript 的源碼那樣的位運(yùn)算,后面接手的人不想打死你才怪。

總結(jié)

CPU 通過晶體管實(shí)現(xiàn)了電路的開關(guān),也就是 0 和 1,然后組成了與或非異或門,進(jìn)一步構(gòu)成邏輯電路,邏輯電路可以實(shí)現(xiàn)加減乘除,構(gòu)成 ALU,加上寄存器等部件就構(gòu)成了 CPU。

所以位運(yùn)算是直接用電路算,效率最高,其他的運(yùn)算最終也會(huì)轉(zhuǎn)為位運(yùn)算。

操作系統(tǒng)文件系統(tǒng)的設(shè)計(jì)就用到了位圖和位運(yùn)算,React 和 Typescript 源碼中也大量用到 flags。但這不意味著業(yè)務(wù)代碼就可以用,因?yàn)闃I(yè)務(wù)代碼還是可維護(hù)性更重要一些。

 

位運(yùn)算里面隱藏著 CPU 實(shí)現(xiàn)的秘密,并不只是一個(gè)炫技的手段那么簡(jiǎn)單。

 

責(zé)任編輯:武曉燕 來源: 神光的編程秘籍
相關(guān)推薦

2017-12-26 15:38:18

iMac隱藏秘密

2013-11-04 17:02:40

Windows 8.1隱藏功能

2022-09-22 13:56:56

線程Java

2019-11-12 13:43:05

云計(jì)算IaaS技術(shù)

2019-02-18 08:17:40

工業(yè)物聯(lián)網(wǎng)IIOT物聯(lián)網(wǎng)

2021-03-18 11:09:13

比特幣加密貨幣區(qū)塊鏈

2021-10-10 15:01:09

Go 源碼Github

2015-12-09 16:21:41

2015-10-26 09:32:16

春雨醫(yī)生微信傳播鏈

2019-09-25 17:22:31

戴爾

2021-04-27 11:15:51

Java 8ConcurrentHBUG

2015-07-30 06:19:48

Linux云計(jì)算原生計(jì)算基金會(huì)

2024-08-08 19:13:19

2015-10-27 09:09:44

2015-11-19 10:59:00

2022-02-07 15:24:53

iOS蘋果系統(tǒng)

2021-08-04 10:14:15

云計(jì)算多云云架構(gòu)

2021-11-09 23:14:01

手機(jī)飛行模式功能

2021-05-29 10:39:21

Android 12翻譯谷歌
點(diǎn)贊
收藏

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