應(yīng)該也差不多了往史,雖然我沒有深入到,它是如何在操作系統(tǒng)層面上工作的佛舱。
不能連續(xù)地一幀一幀地分配椎例,因為這很慢。
我們會在現(xiàn)實中學(xué)習(xí)更多關(guān)于分配的知識以及如何最小化分配(的開銷)请祖。
我們很可能會討論更多關(guān)于CPU 緩存優(yōu)化的內(nèi)容订歪,如果你正在編寫一個包含100萬個元素的集合务热,然后每個元素都會cache miss级及,你會看到一個非常真實的性能差異。如果你所有東西都是連續(xù)的或者碎片的矢否。
實際的訪問 cpu慎陵、緩存 通逞凼可以忽略不計,是通常席纽,但不是總是捏悬。
當(dāng)你調(diào)用new 時,你需要檢查空閑列表润梯,請存內(nèi)存过牙,然后記錄這些。
你要從預(yù)先分配的4gb 內(nèi)存塊中進行對分配纺铭,但他們miss 的數(shù)量 可能不夠造成麻煩寇钉,你唯一可能要處理的是 緩存不命中 問題 cpu cache miss 的問題。
所以理論上講舶赔,如果你預(yù)先分配扫倡,然后你要從預(yù)先分配的4gb 內(nèi)存塊中進行堆分配,
或者你特別需要更多的數(shù)據(jù)竟纳,比如我想加載一個紋理撵溃,這就不適合在棧上分配,你應(yīng)該總在棧上分配蚁袭,性能的不同是因為分配的不同征懈。
在堆上分配的唯一原因,是你不能夠在堆上分配揩悄,事實上,你應(yīng)該盡可能在棧上分配鬼悠,如果可能的話删性。
然后顯然要去到空閑列表亏娜,去檢查我們是否有足夠的內(nèi)存,然后記錄已經(jīng)被拿走了多少內(nèi)存蹬挺,有多少已經(jīng)被分配了维贺?
這是我們堆上的分配,這里調(diào)用構(gòu)造函數(shù)巴帮,它調(diào)用了整個操作符new溯泣,new操作又調(diào)用了malloc.
這是一條cpu指令,放入特定的偏移量的棧指針榕茧。
我們將 assembly output 選成assembly with source code.
按下ctrl+ F7 來進行編譯垃沦,你可能不會注意到區(qū)別,因為你沒有足夠多的cache misses用押,導(dǎo)致出現(xiàn)問題肢簿。
因為你不斷在訪問,棧上的東西是活躍的蜻拨,就像你把函數(shù)放到棧上池充,把東西放到寄存器里,諸如此類缎讼。
事實上收夸,棧上的內(nèi)存距離更近,但是如果只有少量的cache misses 你沒法對這個觀點進行爭論血崭。一些cache misses 對比沒有 cache misses.?
但是如果我們處理數(shù)百萬的 cache misses咱圆,這就是大問題了。
訪問的數(shù)據(jù)在Cache中功氨,稱為hit序苏,反之則稱為“Miss” 。相比之下捷凄,在棧中分配忱详,可能不會得到cache miss.
在我們請求第一個棧上變量之后,
在堆上分配內(nèi)存是一堆的事情跺涤,潛在的成本是巨大的匈睁。
因此它們可以放到cpu 緩存線上(cache line 可理解為 CPU Cache 中的最小緩存單位。)
你的程序需要詢問你的操作系統(tǒng)桶错,我需要更多的內(nèi)存航唆。
超過了操作系統(tǒng)給你的初始分配,超過了空閑列表院刁,
這樣做通常會調(diào)用底層操作系統(tǒng)或平臺的特定函數(shù)糯钙。
你的程序會維護一個叫做空閑列表(free list)的東西。
一條Cpu的刪除指令 就可以釋放所有東西,不需要將棧指針反向移動 然后 返回棧指針地址任岸。
一個叫做malloc 的函數(shù)再榄,memory allocate 的縮寫。
釋放的意思是享潜,釋放內(nèi)存沒有任何開銷困鸥。
delete harray 加上一個數(shù)字操作符[]
內(nèi)存實際上是相互疊加存儲的,棧是倒著來的剑按,是第一個變量value疾就,int value,存儲在更高地址上艺蝴。
它實際上只是添加了安全守衛(wèi)(safety guards)猬腰,以確保我們不會溢出所有的變量。
cccc 在debug模式下吴趴,是說我們還沒有初始化這個value漆诽。
棧通常是一個預(yù)定義大小的內(nèi)存區(qū)域,通常為2兆字節(jié)左右锣枝。
在日志系統(tǒng)或者其他使用場景下厢拭。