成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

計(jì)算機(jī)系統(tǒng)中與存儲(chǔ)有關(guān)的那些事

存儲(chǔ) 存儲(chǔ)軟件
最近工作中,經(jīng)歷了很多項(xiàng)目問題的調(diào)試,把這些問題歸總起來,其中和存儲(chǔ)有關(guān)的,獨(dú)占一半。而存儲(chǔ)對計(jì)算機(jī)系統(tǒng)造成的影響又可分為兩塊:一是系統(tǒng)功能的穩(wěn)健性;二是程序的執(zhí)行效率。

最近工作中,經(jīng)歷了很多項(xiàng)目問題的調(diào)試,把這些問題歸總起來,其中和存儲(chǔ)有關(guān)的,獨(dú)占一半。而存儲(chǔ)對計(jì)算機(jī)系統(tǒng)造成的影響又可分為兩塊:一是系統(tǒng)功能的穩(wěn)健性;二是程序的執(zhí)行效率。

存儲(chǔ)器結(jié)構(gòu)

1.1 存儲(chǔ)器層次結(jié)構(gòu)

由于訪問速度、成本、功耗等指標(biāo)的制約,計(jì)算機(jī)系統(tǒng)中的存儲(chǔ)往往不是作為一個(gè)單一的大塊存在,而是被設(shè)置成一個(gè)多級(jí)的層次結(jié)構(gòu)。作為一個(gè)程序員,需要理解存儲(chǔ)器層次結(jié)構(gòu),因?yàn)樗鼘?yīng)用程序的性能有著巨大的影響。

圖1中展示了一個(gè)典型 計(jì)算機(jī)系統(tǒng)的存儲(chǔ)層級(jí)結(jié)構(gòu)。和金字塔模型很像,越靠近金字塔頂端的存儲(chǔ)器,離CPU越近,訪問更便利且訪問速度快,但同時(shí)它們的容量也越來越小;反之越靠近底層,存儲(chǔ)容量越大,訪問速度卻越來越慢。

[[235311]]

最高層的L0,是CPU寄存器,CPU可以在一個(gè)時(shí)鐘周期內(nèi)訪問他們;接下來是一個(gè)或多個(gè)小型到中型的基于SRAM的高速緩存存儲(chǔ)器,可以在幾個(gè)CPU時(shí)鐘周期內(nèi)訪問它們;然后是一個(gè)大的基于DRAM的主存,可以在幾十到幾百個(gè)時(shí)鐘周期內(nèi)訪問它們;接下來是慢速但容量很大的本地磁盤;最后,甚至有些系統(tǒng)會(huì)通過網(wǎng)絡(luò)訪問其遠(yuǎn)程服務(wù)器上的磁盤。

圖1 存儲(chǔ)器層次結(jié)構(gòu)

 

高速緩存可以存在一級(jí)或多級(jí),甚至不存在于一些低性能的單片機(jī)中。TI C64X架構(gòu)中設(shè)計(jì)有2級(jí)的高速緩存,其數(shù)據(jù)和代碼的存取機(jī)制在本訂閱號(hào)之前的文章“TI C6000 數(shù)據(jù)存儲(chǔ)處理與性能優(yōu)化”中有過描述。

1.2 存儲(chǔ)器的訪問

一個(gè)編寫良好的計(jì)算機(jī)程序常常具有良好的局部性(locality)。

局部性通常有兩種不同的形式:時(shí)間局部性和空間局部性。

  • 時(shí)間局部性:在一個(gè)具有良好時(shí)間局部性的程序中,被訪問過一次的內(nèi)存位置很可能在不遠(yuǎn)的將來再被多次訪問 。
  • 空間局部性:在一個(gè)具有良好空間局部性的程序中,如果一個(gè)內(nèi)存位置被訪問 了一次,那么程序很可能在不遠(yuǎn)的將來訪問 附近的一個(gè)內(nèi)存位置。

例如對一個(gè)二維數(shù)組求和:

  1. for (i=0; i<M; i++) 
  2.      for(j=0; j<N; j++) 
  3.           sum += data_tab[i][j]; 

其中,sum在循環(huán)迭代中被多次訪問,它具有良好的時(shí)間局部性,但因其為標(biāo)量,因此沒有空間局部性。對二維數(shù)組data_tab而言,其元素在存儲(chǔ)中順序存儲(chǔ),因此有好的空間局部性,但由于其每個(gè)元素只訪問一次,因此時(shí)間局部性很差。

另外,假設(shè)把上面第三行替換成:

  1. sum += data_tab[j][i]; 

由于二維數(shù)組是按行依次存儲(chǔ),則每次循環(huán)對內(nèi)存訪問的步長由1變?yōu)镹,空間局部性變差。像這樣看上去對程序很小的改動(dòng)對它的局部性有很大的影響。

存儲(chǔ)類型

2.1 隨機(jī)訪問存儲(chǔ)器(RAM)

上電使用,掉電存儲(chǔ)內(nèi)容丟失。

靜態(tài)RAM(SRAM):存儲(chǔ)單元具有雙穩(wěn)態(tài)特性,上電就能保持它的值,對光和電噪聲等干擾不敏感。它使用晶體管多,因而密集度低,更貴,功耗更大。

動(dòng)態(tài)RAM(DRAM):對每個(gè)位存儲(chǔ)為對一個(gè)電容的充電,因漏電的原因需要不斷刷新來保持存儲(chǔ)值。

  • SDRAM(Synchronous DRAM):用與驅(qū)動(dòng)內(nèi)存控制器相同的外部時(shí)鐘信號(hào)的上升沿,來作為控制信號(hào)。
  • DDR SDRAM(Double Data-Rate Synchronous DRAM):通過使用兩個(gè)時(shí)鐘沿作為控制信號(hào),從而使DRAM的速度翻倍。它是用提高有效帶寬的很小的預(yù)緩沖區(qū)的大小來劃分的,如DDR(2位)、DDR2(4位)、DDR3(8位)。

表1 SRAM與DRAM性能比較

 

2.2 非易失性存儲(chǔ)器

非易失性存儲(chǔ)器,即使在關(guān)電后仍能保存著它們的信息。由于歷史的原因,它們也被整體成稱為ROM(Read Only Memory),但很多ROM類型是即可以讀也可以寫的。

PROM(Programble ROM):只能被編程一次,PROM的每個(gè)存儲(chǔ)器單元有一種熔絲,只能用高電流熔斷一次。

EPROM(Erasable Programble ROM):可擦寫可編程,對它的編程是通過一種把1寫入EPROM的特殊設(shè)備來完成的。

EEPROM(Electrically Erasable Programble ROM):電子可擦除,不需要一個(gè)物理上獨(dú)立的編程設(shè)備,因此可以直接在芯片上編程,能被編程的次數(shù)可以達(dá)到10e5次。

閃存(flash):基于EEPROM的一類非易失性存儲(chǔ)器。對它寫數(shù)據(jù)必須先將芯片中對應(yīng)的內(nèi)容清空,然后再寫入,也就是通常說的“先擦后寫 ”。

  • NAND flash:對它的操作以“塊 ”為基本單位,因此要修改一個(gè)字節(jié),必須重寫整個(gè)數(shù)據(jù)塊。它的容量大,適合做大量數(shù)據(jù)的存儲(chǔ)。
  • NOR flash:對它的操作以“字 ”為基本單位。它的容量相對較小,成本大,一般用來存儲(chǔ)程序。

2.3 磁盤

磁盤由盤片構(gòu)成,它是廣為應(yīng)用的保存大量數(shù)據(jù)的存儲(chǔ)設(shè)備。不過從磁盤上讀信息的時(shí)間為毫秒級(jí),比從DRAM讀慢了10萬倍,比從SRAM讀慢了100萬倍。

棧和堆

3.1 棧(stack)

棧是一個(gè)“后進(jìn)先出”的存儲(chǔ)空間,程序運(yùn)行中,代碼“過程 ”涉及到的返回地址、過程參數(shù)、需要保存的寄存器信息都被壓入棧中,過程中聲明的臨時(shí)變量也是在棧中開辟存儲(chǔ)。

過程的形式多樣:函數(shù)、方法、子例程、中斷處理函數(shù)等。當(dāng)過程需要的存儲(chǔ)空間超出寄存器能夠存放的大小時(shí),就會(huì)在棧上分配空間,這部分空間稱為過程的棧幀。

通常,棧底位于高地址,隨著數(shù)據(jù)的壓入,棧向低地址方向增長,而棧指針指向棧頂。將棧指針減少一個(gè)適當(dāng)?shù)牧浚梢詾闆]有指定初始值的數(shù)據(jù),在棧上分配空間;類似的,可以通過增加棧指針來釋放空間。因?yàn)闂5奈恢萌Q于.stack段分配在什么地方,所以棧的實(shí)際地址是在連接時(shí)決定的。

假設(shè)過程P調(diào)用過程Q時(shí),相關(guān)的控制和數(shù)據(jù)信息添加到棧尾,當(dāng)Q返回時(shí),這些信息會(huì)釋放掉。如果存在多級(jí)調(diào)用(包括遞歸調(diào)用),較早的棧幀也會(huì)累積下來,直到它對應(yīng)的過程結(jié)束。

圖2 通用的棧幀結(jié)構(gòu)

 

棧空間的大小可以在鏈接命令文件中,使用-stack選項(xiàng)進(jìn)行設(shè)定。在對TI C64X架構(gòu)芯片進(jìn)行編程時(shí),如果用戶沒有自己設(shè)定,系統(tǒng)默認(rèn)棧的尺寸為1KB。注意:編譯器在編譯期間和運(yùn)行期間都不進(jìn)行對棧溢出的檢查,因此對棧空間的管理上需格外小心。

3.2 堆(heap)

堆是用于動(dòng)態(tài)內(nèi)存分配的一個(gè)存儲(chǔ)區(qū)域,動(dòng)態(tài)分配的對象不是可直接尋址的,它們總是用指針來訪問。動(dòng)態(tài)內(nèi)存分配器將堆視為一組不同大小的塊的集合來維護(hù)。每個(gè)塊就是一個(gè)連續(xù)的虛擬內(nèi)存片,要么是已分配的,要么是空閑的。一個(gè)已分配的塊保持已分配狀態(tài),直到他被釋放,這種釋放要么是應(yīng)用程序顯式執(zhí)行的,要么是內(nèi)存分配器自身隱式執(zhí)行的。

C標(biāo)準(zhǔn)庫提供一個(gè)稱為malloc程序包的顯式分配器,程序通過調(diào)用malloc函數(shù)來從堆中分配塊。malloc函數(shù)返回一個(gè)指針,指向大小至少為size字節(jié)的內(nèi)存塊,這個(gè)塊會(huì)為可能包含在這個(gè)塊內(nèi)的任何數(shù)據(jù)對象類型做對齊。與malloc相對應(yīng)的是free程序包,用于釋放已分配的內(nèi)存塊。

下圖直接截取深入理解計(jì)算機(jī)系統(tǒng)這本書中,用一個(gè)16字的小堆來展示的malloc和free是如何管理堆空間的:

程序使用動(dòng)態(tài)內(nèi)存分配的最重要原因是,經(jīng)常直到程序?qū)嶋H運(yùn)行時(shí)才知道某些數(shù)據(jù)結(jié)構(gòu)的大小。

堆位于段.sysmem中,可分配動(dòng)態(tài)存儲(chǔ)池的大小,僅僅受限于系統(tǒng)中實(shí)際的存儲(chǔ)容量。 堆空間的大小可以在鏈接命令文件中,使用-heap選項(xiàng)進(jìn)行設(shè)定。在對TI C64X架構(gòu)芯片進(jìn)行編程時(shí),如果用戶沒有自己設(shè)定,系統(tǒng)默認(rèn)堆的尺寸為1KB。

C編程中常見的與內(nèi)存有關(guān)的錯(cuò)誤

在我們項(xiàng)目的調(diào)試中,死機(jī)現(xiàn)象被認(rèn)為是最讓人頭疼的問題,因?yàn)檫@類問題往往很難復(fù)現(xiàn),而即便是找到了復(fù)現(xiàn)的規(guī)律,也很難通過跟蹤調(diào)試來斷定問題所屬的區(qū)域。由軟件造成死機(jī)的因素,可大致分為兩類:內(nèi)存操作錯(cuò)誤和線程阻塞。

線程阻塞也有很多表現(xiàn)方式,如高優(yōu)先級(jí)線程堆積、程序陷入異常處理流程、死循環(huán)等等。所幸的是,線程阻塞要么很好復(fù)現(xiàn),要么被追蹤到一次就能立馬找出癥結(jié)所在,可面對內(nèi)存錯(cuò)誤造成的死機(jī)就不那么容易解決了。《深入理解計(jì)算機(jī)系統(tǒng)》這本書中也講到:與內(nèi)存有關(guān)的錯(cuò)誤,屬于那些最令人驚恐的錯(cuò)誤,因?yàn)樗麄冊跁r(shí)間和空間上,經(jīng)常在舉措無緣一段距離之后才表現(xiàn)出來,將錯(cuò)誤的數(shù)據(jù)選擇錯(cuò)誤的位置,你的程序可能在最終失敗之前運(yùn)行了好幾個(gè)小時(shí),其實(shí)程序終止的位置距離處的位置已經(jīng)很遠(yuǎn)了。

內(nèi)存操作錯(cuò)誤為什么會(huì)造成死機(jī)?舉個(gè)簡單的類比:一套性能完整的代碼就好比是一幢設(shè)計(jì)建造完好的房子,而內(nèi)存操作錯(cuò)誤就像是突然拆除或篡改了支撐房屋結(jié)構(gòu)或運(yùn)轉(zhuǎn)的關(guān)鍵部位,這一突發(fā)錯(cuò)誤完全超出設(shè)計(jì)意料之外,引發(fā)一連串的惡果也就在所難免。下面是一些常見的內(nèi)存錯(cuò)誤操作的例子(真實(shí)的情況遠(yuǎn)不止這些,更多情況可參考《深入理解計(jì)算機(jī)系統(tǒng)》這本書):

4.1 數(shù)組越界

  1. int data_tab[100];  
  2. int i; 
  3.    
  4.  
  5. for(i=0; i<=100; i++)  
  6.  
  7.      data_tab[i] = i;  

這個(gè)例子中data_tab占100個(gè)int型長度,但循環(huán)卻進(jìn)行了101次。C對于數(shù)組應(yīng)用不進(jìn)行任何邊界檢查,而且局部變量和狀態(tài)信息(例如保存的寄存器值和返回地址)存放在棧中,這兩種情況結(jié)合到一起就能導(dǎo)致嚴(yán)重的程序錯(cuò)誤,對越界數(shù)組元素的寫操作,會(huì)破壞存儲(chǔ)在棧中的狀態(tài)信息。

另一種情況是data_tab[]是全局?jǐn)?shù)組,這樣的越界將引起對數(shù)組尾部其它存儲(chǔ)內(nèi)容的修改,倘若被篡改的存儲(chǔ)區(qū)域剛好涉及到代碼的關(guān)鍵流程判斷,意味著異常流程的出現(xiàn)。

4.2 間接引用壞指針

  1. scanf("%d", &val); 

錯(cuò)誤寫成:

  1. scanf("%d", val); 

在這種情況下,scanf將val的內(nèi)容解釋為一個(gè)地址,并試圖將一個(gè)字節(jié)寫到這個(gè)位置。在最好的情況下,程序立即異常終止,在最糟糕的情況下,val的內(nèi)容對應(yīng)于內(nèi)存的某個(gè)合法的讀寫區(qū)域,于是我們就覆蓋了這塊內(nèi)存,就通常會(huì)在相當(dāng)長的一段時(shí)間以后,造成災(zāi)難性的令人困惑的后果。

4.3 誤解指針運(yùn)算

  1. int *search(int *p, int val)  
  2.  
  3.      while(*p && *p != val) 
  4.      p += sizeof(int)  // should be p++    
  5.  
  6.      return p; 

這種錯(cuò)誤是忘記了指針的算術(shù)操作是以它指向的對象的大小為單位來進(jìn)行的。假設(shè)這里int占四個(gè)字節(jié),原本掃描每個(gè)int變成了每四個(gè)int掃描一次。

4.4 引用不存在的變量

  1. int *stackref() 
  2.  
  3.  
  4.      int val; 
  5.  
  6.      int *p; 
  7.  
  8.   
  9.  
  10.      p = &val; 
  11.  
  12.   
  13.  
  14.      return p; 
  15.  

這個(gè)函數(shù)返回一個(gè)指針,指向棧里的一個(gè)局部變量。盡管p仍指向一個(gè)合法的內(nèi)存地址,是它已經(jīng)不再指向一個(gè)合法的變量了。要知道,局部變量val在函數(shù)返回時(shí),將會(huì)被釋掉。

4.5 引用空閑堆塊中的數(shù)據(jù)

  1. int *heapref() 
  2.  
  3.  
  4.      int *x, *y; 
  5.  
  6.   
  7.  
  8.      x = (int *)malloc(sizeof(int)); 
  9.  
  10.      ... 
  11.  
  12.      free(x); 
  13.  
  14.   
  15.  
  16.      y = x; 
  17.  
  18.      ... 
  19.  
  20.      return y; 
  21.  

這里y錯(cuò)誤的引用已經(jīng)被釋放的堆塊的數(shù)據(jù)和指針x。申請的堆塊一旦被釋放,雖然之前指向該堆塊的指針x并沒有變化,但它指向的區(qū)域數(shù)據(jù)已經(jīng)不再有效了。

4.6 引起內(nèi)存泄漏

  1. void leak(int n) 
  2.  
  3.  
  4.      x = (int *)malloc(n*sizeof(int)); 
  5.  
  6.   
  7.  
  8.      return
  9.  

這個(gè)函數(shù)中分配了一個(gè)堆塊,但沒釋放就返回。如果經(jīng)常調(diào)用leak,那么漸漸的堆里就會(huì)充滿了垃圾,最糟糕的情況下會(huì)占用整個(gè)內(nèi)存地址空間。內(nèi)存泄漏是緩慢、隱性的殺手。

參考文獻(xiàn)

【1】BRYANT R E, O’HALLARON D R. Computer Systems: A Programmer’s Perspective[M]. 3 edition. Boston: Pearson, 2015.(譯名:深入理解計(jì)算機(jī)系統(tǒng))

【2】田黎育,何佩琨,朱夢宇. TMS320C6000系列DSP編程工具與指南[M].北京:清華大學(xué)出版社 2006.

【3】TMS320C6000 Assembly Language Tools v7.4--SPRU186W,2012

【4】嵌入式開發(fā)之NorFlash 和NandFlash-tiger-john的CSDN博客

 

責(zé)任編輯:武曉燕 來源: IT學(xué)習(xí)樂園
相關(guān)推薦

2014-04-10 09:40:51

System 360計(jì)算機(jī)計(jì)算機(jī)系統(tǒng)

2013-03-12 10:19:20

計(jì)算機(jī)內(nèi)存芯片數(shù)據(jù)

2022-03-30 15:25:28

鏈接過程計(jì)算機(jī)系統(tǒng)程序

2014-06-06 16:08:17

初志科技

2015-08-27 17:08:46

大數(shù)據(jù)

2015-07-23 09:30:43

爛代碼程序員

2010-03-08 10:48:09

2010-04-02 09:42:24

2018-10-18 14:50:52

2012-09-12 09:59:26

云計(jì)算超級(jí)計(jì)算機(jī)數(shù)據(jù)中心

2018-04-11 08:54:16

Linux ARM存儲(chǔ)分布

2019-11-19 14:48:00

Kafka文件存儲(chǔ)

2015-12-11 10:02:51

2009-07-04 09:38:07

2009-01-05 13:23:25

軟件設(shè)計(jì)師筆記

2021-10-19 21:39:51

Unsafe構(gòu)造器內(nèi)存

2021-08-11 21:46:47

MySQL索引join

2017-03-08 08:53:44

Git命令 GitHub

2020-12-17 08:09:25

計(jì)算機(jī)網(wǎng)絡(luò)網(wǎng)絡(luò)TCP

2023-10-11 18:30:39

Web系統(tǒng)程序
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 热99| 日韩2020狼一二三 | 人人做人人澡人人爽欧美 | 精品国产一区二区三区性色av | 韩日一区二区 | 欧美三级视频在线观看 | 91免费看片 | 成人av一区二区三区 | 国产色网站 | www.玖玖玖| 国产一级一级国产 | 久久精品免费观看 | 久久精品在线 | 99精品国产一区二区青青牛奶 | 成人免费视频网站在线看 | 日韩2020狼一二三 | 国产丝袜一区二区三区免费视频 | 人人干视频在线 | 日日夜夜精品 | 色婷婷av一区二区三区软件 | 久久精品小视频 | 成人欧美一区二区 | 亚洲福利av| 亚洲最大av | 日本成人毛片 | 日日做夜夜爽毛片麻豆 | 国产乱人伦 | 91新视频 | 三级在线免费观看 | 免费激情av | 亚洲精品一区二 | 久久小视频 | 亚洲国产精品99久久久久久久久 | 欧美一级二级视频 | 婷婷去俺也去 | 国产精品99久久久久久www | 不卡视频一区二区三区 | 成人一区二区三区视频 | 男女视频在线观看 | 高清av一区 | 一区二区三区在线观看视频 |