壓榨CPU性能帶來的問題
由于CPU速度非常快,且價格非常昂貴,我們必須得 充分壓榨CPU ,得像生產隊的驢一樣,讓它不停地工作!
為了合理利用 CPU 的高性能,同時盡可能地節約成本,現代計算機將這些儲存器充分的結合起來,由于這些硬件的數據存取速度差異導致了計算機系統編程中的各種問題:
有序性問題
為了充分壓榨CPU的性能, CPU 會對指令亂序執行或者語言的編譯器會指令重排 ,讓CPU一直工作不停歇,但同時會導致有序性
問題。
在CPU中為了能夠讓指令的執行盡可能地同時運行起來,采用了 指令流水線 。一個 CPU 指令的執行過程可以分成 4 個階段:取指、譯碼、執行、寫回
。這 4 個階段分別由 4 個獨立物理執行單元來完成。
理想的情況是:指令之間無依賴,可以使流水線的并行度最大化。但是如果兩條指令的前后存在依賴關系,比如數據依賴,控制依賴等,此時后一條語句就必需等到前一條指令完成后,才能開始。所以CPU為了提高流水線的運行效率,對無依賴的前后指令做 適當的亂序和調度 。
還有一種情況 編譯器會指令重排 ,比如java語言,JVM 的編譯器會對其指令進行重排序的優化( 指令重排 )。
所謂指令重排是指在不改變原語義的情況下,通過調整指令的執行順序讓程序運行的更快。JVM中并沒有規定編譯器優化相關的內容,也就是說JVM可以自由的進行指令重排序的優化。
無論是編譯期的指令重排還是 CPU 的亂序執行 ,主要都是為了讓 CPU 內部的指令流水線可以“填滿”,提高指令執行的并行度,充分利用CPU的高性能。
可見性問題
為了平衡CPU的寄存器和內存的速度差異,計算機的CPU 增加了高速緩存,但同時導致了 可見性
問題。我們知道當程序執行時,一般CPU會去從內存中讀取數據,來進行計算。CPU計算完之后,需要把數據重新放回到內存中。
當CPU的多個核心參與一個程序的運行,從內存中讀取一個共享變量的數據,當不同核心間進行了各自的計算,把計算后的值放入自己的緩存中而不選擇立即寫入內存中(CPU寫入內存的時機是不確定的)。那么在CPU的緩存中,這個共享變量有可能存放著不同的數據,這就導致了緩存的可見性問題。即一個線程對數據的修改無法對其他線程可見。
原子性問題
為了平衡CPU 與 I/O 設備
的速度差異,操作系統增加了進程、線程
概念,以分時復用 CPU,但同時導致了原子性
問題。
原子操作就是不可分割的操作,在計算機中,就是指不會因為線程調度被打斷的操作。
當一個程序去I/O 設備讀取數據, 由于I/O 設備數據存入讀取速度,相比于CPU的執行速度來說度日如年,CPU這么牛逼這么昂貴的寶貝,怎么能讓它歇著,得讓它一直干活,去切換執行其他程序。也就是將CPU的時間進行分片,讓各個程序在CPU上輪轉執行。但被剝奪執行權的程序,等它從IO讀取完數據后,還是得讓CPU繼續執行的,這時需要一個數據結構來保存,以便之后恢復繼續執行,這個就是進程。
一開始進程中 只有一個"執行流",干活的人就一個。隨著任務越來越多,發現進程不夠用了,經常導致整個程序被阻塞,這時計算機讓進程有多個執行流,干活的人變多了,那程序就不會再被阻塞了,"執行流" 就是線程。
如何解決這3個問題,就是并發、多線程需要處理的事,當然這是后話。
參考資料:
《深入理解計算機系統》
《計算機組成原理》
《計算機組成原理》--唐朔飛
https://zhuanlan.zhihu.com/p/379947484
-
cpu
+關注
關注
68文章
10829瀏覽量
211196 -
計算機系統
+關注
關注
0文章
281瀏覽量
24089 -
運算器
+關注
關注
1文章
163瀏覽量
16563
發布評論請先 登錄
相關推薦
評論