下面的每一條戒律都将有(yǒu)效地影(yǐng)響代碼的性能和(hé)可(kě)伸縮性。換句話(huà)說,盡可(kě)能不要照着戒律去做(zuò)!下面,我将解釋如何破壞他們以便提高(gāo)性能和(hé)可(kě)伸縮性。
下面的每一條戒律都将有(yǒu)效地影(yǐng)響代碼的性能和(hé)可(kě)伸縮性。換句話(huà)說,盡可(kě)能不要照着戒律去做(zuò)!下面,我将解釋如何破壞他們以便提高(gāo)性能和(hé)可(kě)伸縮性。
1、應該分配和(hé)釋放多(duō)個(gè)對象
你(nǐ)應該盡量避免過量分配內(nèi)存,因為(wèi)內(nèi)存分配可(kě)能是代價高(gāo)昂的。釋放內(nèi)存塊可(kě)能更昂貴,因為(wèi)大(dà)多(duō)數(shù)分配算(suàn)符總是企圖連接臨近的已釋放的內(nèi)存塊成為(wèi)更大(dà)的塊。直到Windows NT? 4.0 service pack 4.0,在多(duō)線程處理(lǐ)中,系統堆通(tōng)常都運行(xíng)得(de)很(hěn)糟。堆被一個(gè)全局鎖保護,并且在多(duō)處理(lǐ)器(qì)系統上(shàng)是不可(kě)擴展的。
2.不應該考慮使用處理(lǐ)器(qì)高(gāo)速緩存
大(dà)多(duō)數(shù)人(rén)都知道(dào)由虛拟內(nèi)存子系統導緻的hard 頁錯誤代價很(hěn)高(gāo),最好避免。但(dàn)是許多(duō)人(rén)認為(wèi)其他內(nèi)存訪問方法沒有(yǒu)什麽區(qū)别。自從80486以後,這一觀點就不對了。現代的CPUs比RAM要快得(de)多(duō), RAM至少(shǎo)需要兩級內(nèi)存緩存 ,高(gāo)速L1 緩存能保存8KB數(shù)據和(hé)8KB指令,而較慢的L2 緩存能保存幾百KB的數(shù)據和(hé)代碼,這些(xiē)數(shù)據和(hé)代碼混合在一起。
L1 緩存中內(nèi)存區(qū)域的一個(gè)引用需要一個(gè)時(shí)鍾周期,L2 緩存的引用需要4到7個(gè)時(shí)鍾周期,而主內(nèi)存的引用需要許多(duō)個(gè)處理(lǐ)器(qì)時(shí)鍾周期。後一數(shù)字不久将會(huì)超過100個(gè)時(shí)鍾周期。在許多(duō)方面,緩存像一個(gè)小(xiǎo)型的,高(gāo)速的,虛拟內(nèi)存系統。
至于和(hé)緩存有(yǒu)關的基本內(nèi)存單元不是字節而是緩存列。Pentium 緩存列有(yǒu)32個(gè)字節寬。Alpha 緩存列有(yǒu)64個(gè)字節寬。這意味着在L1 緩存中隻有(yǒu)512個(gè)slot給代碼和(hé)數(shù)據。如果多(duō)個(gè)數(shù)據一起使用(時(shí)間(jiān)位置)而并不存儲在一起(空(kōng)間(jiān)位置),性能會(huì)很(hěn)差。數(shù)組的空(kōng)間(jiān)位置很(hěn)好,而相互連接的列表和(hé)其他基于指針的數(shù)據結構的位置往往很(hěn)差。
把數(shù)據打包到同一個(gè)緩存列中通(tōng)常會(huì)有(yǒu)利于提高(gāo)性能,但(dàn)是它也會(huì)破壞多(duō)處理(lǐ)器(qì)系統的性能。內(nèi)存子系統很(hěn)難協調處理(lǐ)器(qì)間(jiān)的緩存。如果一個(gè)被所有(yǒu)處理(lǐ)器(qì)使用的隻讀數(shù)據,和(hé)一個(gè)由一個(gè)處理(lǐ)器(qì)使用并頻繁更新的數(shù)據共享一個(gè)緩存列,那(nà)麽緩存将會(huì)花(huā)費很(hěn)長時(shí)間(jiān)更新這個(gè)緩存列的拷貝。這個(gè)Ping-Pong高(gāo)速遊戲通(tōng)常被稱為(wèi)"緩存 sloshing"。如果隻讀數(shù)據在一個(gè)不同的緩存 列中,就可(kě)以避免sloshing。
對代碼進行(xíng)空(kōng)間(jiān)優化比進行(xíng)速度優化效率更高(gāo)。代碼越少(shǎo),代碼所占的頁也越少(shǎo),這樣需要的運行(xíng)設置和(hé)産生(shēng)的頁錯誤也會(huì)更少(shǎo),同時(shí)占據的緩存 列也會(huì)更少(shǎo)。然而,某些(xiē)核心函數(shù)應該進行(xíng)速度優化。可(kě)以利用profiler去識别這些(xiē)函數(shù)。
3.決不要緩存頻繁使用的數(shù)據。
軟件緩存可(kě)以被各種應用程序使用。當一個(gè)計(jì)算(suàn)代價很(hěn)高(gāo)時(shí),你(nǐ)會(huì)保存結果的一個(gè)拷貝。這是一個(gè)典型的時(shí)空(kōng)折中方法:犧牲一些(xiē)存儲空(kōng)間(jiān)以節省時(shí)間(jiān)。如果做(zuò)得(de)好,這種方法可(kě)能非常有(yǒu)效。
你(nǐ)必須正确地進行(xíng)緩存。如果緩存了錯誤數(shù)據,就會(huì)浪費存儲空(kōng)間(jiān)。如果緩存得(de)太多(duō),其他操作(zuò)可(kě)以使用的內(nèi)存将會(huì)很(hěn)少(shǎo)。如果緩存得(de)太少(shǎo),效率又會(huì)很(hěn)低(dī),因為(wèi)你(nǐ)必須重新計(jì)算(suàn)被緩存遺漏的數(shù)據。如果将時(shí)間(jiān)敏感數(shù)據緩存得(de)時(shí)間(jiān)過長,這些(xiē)數(shù)據将會(huì)過時(shí)。一般,服務器(qì)更關心的是速度而不是空(kōng)間(jiān),所以他們要比桌面系統進行(xíng)更多(duō)的緩存。一定要定期去除不用的緩存,否則将會(huì)有(yǒu)運行(xíng)設置問題。
4.應該創建多(duō)個(gè)線程,越多(duō)越好。
調整服務器(qì)中起作(zuò)用的線程數(shù)目是很(hěn)重要的。如果線程是I/O-bound的,将會(huì)花(huā)費很(hěn)多(duō)時(shí)間(jiān)用來(lái)等待I/O的完成-一個(gè)被阻塞的線程就是一個(gè)不做(zuò)任何有(yǒu)用工作(zuò)的線程。加入額外的線程可(kě)以增加通(tōng)量,但(dàn)是加入過多(duō)的線程将會(huì)降低(dī)服務器(qì)的性能,因為(wèi)上(shàng)下文交換将會(huì)成為(wèi)一個(gè)重大(dà)的overhead。上(shàng)下文交換速度應該低(dī)的原因有(yǒu)三個(gè):上(shàng)下文交換是單純的overhead,對應用程序的工作(zuò)沒有(yǒu)任何益處;上(shàng)下文交換用盡了寶貴的時(shí)鍾周期;最糟的是,上(shàng)下文交換将處理(lǐ)器(qì)的緩存填滿了沒用的數(shù)據,替換這些(xiē)數(shù)據是代價高(gāo)昂的。
有(yǒu)很(hěn)多(duō)事情是依靠你(nǐ)的線程化結構的。每個(gè)客戶端一個(gè)線程是絕對不合适的。因為(wèi)對于大(dà)量用戶端,它的擴展性不好。上(shàng)下文交換變得(de)難以忍受, Windows NT用盡了資源。線程池模型會(huì)工作(zuò)得(de)更好,在這種方法中一個(gè)工人(rén)線程池将處理(lǐ)一條請(qǐng)求列,因為(wèi)Windows 2000提供了相應的APIs,如QueueUserWorkItem。
5.應該對數(shù)據結構使用全局鎖
使數(shù)據線程安全的最簡單方法是把它套上(shàng)一把大(dà)鎖。為(wèi)簡單起見,所有(yǒu)的東西都用同一把鎖。這種方法會(huì)有(yǒu)一個(gè)問題:序列化。為(wèi)了得(de)到鎖,每一個(gè)要處理(lǐ)數(shù)據的線程都必須排隊等候。如果線程被一把鎖阻塞,它沒有(yǒu)在做(zuò)任何有(yǒu)用的事。當服務器(qì)的負載較輕時(shí),這個(gè)問題并不常見,因為(wèi)一次可(kě)能隻有(yǒu)一個(gè)線程需要鎖。在負載很(hěn)重的情況下,對鎖的激烈争奪可(kě)能就會(huì)成為(wèi)一個(gè)大(dà)問題。
設想在多(duō)車(chē)道(dào)高(gāo)速公路上(shàng)發生(shēng)了一個(gè)意外事故,這條高(gāo)速公路上(shàng)的所有(yǒu)車(chē)輛(liàng)都被轉向一條狹窄的道(dào)路。如果車(chē)輛(liàng)很(hěn)少(shǎo),這一轉換對交通(tōng)流的速率的影(yǐng)響可(kě)以忽略。如果車(chē)輛(liàng)很(hěn)多(duō),當車(chē)輛(liàng)慢慢并入那(nà)條單通(tōng)道(dào)時(shí),交通(tōng)阻塞會(huì)延伸幾英裏。
有(yǒu)幾種技(jì)術(shù)能夠減少(shǎo)鎖競争。
· 不要過分保護,也就是說,不是非常必要不要鎖住數(shù)據。隻有(yǒu)需要時(shí)才去持有(yǒu)鎖,而且時(shí)間(jiān)不要過長。不要在大(dà)段代碼周圍或頻繁執行(xíng)的代碼中沒必要地使用鎖,這一點很(hěn)重要。
· 對數(shù)據進行(xíng)分割,使它能夠用一套獨立的鎖保護。例如,一個(gè)符号表可(kě)以按标識符的第一個(gè)字母分割,這樣在修改名字以Q開(kāi)頭的符号的值時(shí),就不會(huì)去讀名字以H開(kāi)頭的符号的值。
· 使用APIs的Interlocked 系列(InterlockedIncrement,InterlockedCompareExchangePointer等)自動修改數(shù)據而不需要鎖。
· 當數(shù)據不是經常被修改時(shí)可(kě)以使用多(duō)讀者/單作(zuò)者(multi-reader/single-writer)鎖。你(nǐ)将獲得(de)更好的并發性,盡管鎖操作(zuò)的代價将更高(gāo)并且你(nǐ)可(kě)能會(huì)冒餓死作(zuò)者的危險。
· 在關鍵部分使用循環計(jì)數(shù)器(qì)。參見Windows NT 4.0 service pack 3中的SetCriticalSectionSpinCount API。
· 如果你(nǐ)不能得(de)到鎖,使用TryEnterCriticalSection并做(zuò)一些(xiē)其他的有(yǒu)用的工作(zuò)。
高(gāo)競争導緻serialization,serialization導緻降低(dī)CPU的利用率,這促使用戶加入更多(duō)的線程,結果事情變得(de)更糟。
6.不必注意多(duō)處理(lǐ)器(qì)機器(qì)
你(nǐ)的代碼在多(duō)處理(lǐ)器(qì)系統上(shàng)比在單處理(lǐ)器(qì)系統上(shàng)運行(xíng)得(de)還(hái)要糟,這可(kě)能是件令人(rén)惡心的事。一個(gè)很(hěn)自然的想法是,在一個(gè)N維系統上(shàng)運行(xíng)N次會(huì)更好。性能很(hěn)差的原因是競争:鎖競争,總線競争,和(hé)/或緩存列競争。處理(lǐ)器(qì)都在是争奪共享資源的所有(yǒu)權,而不是做(zuò)更多(duō)的工作(zuò)。
如果你(nǐ)一定要編寫多(duō)線程應用程序的話(huà),你(nǐ)應該在多(duō)處理(lǐ)器(qì)盒上(shàng)對你(nǐ)的應用程序進行(xíng)強度測試和(hé)性能測試。單處理(lǐ)器(qì)系統通(tōng)過時(shí)間(jiān)分片地執行(xíng)線程而提供一個(gè)并發性的假象。多(duō)處理(lǐ)器(qì)盒具有(yǒu)真正的并發性,競争環境和(hé)競争更容易發生(shēng)。
7.應該始終使用模塊化調用;他們很(hěn)有(yǒu)趣。
利用同步模塊化調用來(lái)執行(xíng)I/O操作(zuò)對大(dà)多(duō)數(shù)桌面應用程序來(lái)說是合适的。但(dàn)是,他們不是使用服務器(qì)上(shàng)的CPU(s)的好方法。I/O操作(zuò)要花(huā)費上(shàng)百萬個(gè)時(shí)鍾周期來(lái)完成,這些(xiē)時(shí)鍾周期本來(lái)可(kě)以被更好地利用。利用異步I/O你(nǐ)能得(de)到顯著提高(gāo)的用戶請(qǐng)求率和(hé)I/O通(tōng)量,不過增加了額外的複雜性。
如果你(nǐ)有(yǒu)需要花(huā)費很(hěn)長時(shí)間(jiān)的模塊化調用或I/O操作(zuò),你(nǐ)應該考調撥多(duō)少(shǎo)資源給他們。你(nǐ)想使用所有(yǒu)的線程還(hái)是有(yǒu)個(gè)限制(zhì)?一般地,使用有(yǒu)限的幾個(gè)線程要好些(xiē)。構建一個(gè)小(xiǎo)的線程池和(hé)隊列,利用隊列來(lái)安排線程的工作(zuò)完成模塊化調用。這樣,其他線程就可(kě)以拾取和(hé)處理(lǐ)你(nǐ)的非模塊化的請(qǐng)求。
8.不要進行(xíng)測量
當你(nǐ)能夠測量你(nǐ)所談論的事情并用數(shù)字表達它時(shí),這就表示你(nǐ)對他有(yǒu)了一定的了解;但(dàn)是如果你(nǐ)不能用數(shù)字表達時(shí),你(nǐ)的知識是貧瘠的不能令人(rén)滿意的;這可(kě)能是知識的開(kāi)始,但(dàn)這時(shí)你(nǐ)簡直不可(kě)能将你(nǐ)的思想提高(gāo)到科學的水(shuǐ)平。
- Lord Kelvin (William Thomson)
如果不測量你(nǐ)就不能了解應用程序的特性。你(nǐ)在黑(hēi)暗中摸索,一半是靠猜測。如果不識别性能問題,你(nǐ)就不能做(zuò)任何改進或做(zuò)出工作(zuò)量計(jì)劃。
測量包括黑(hēi)匣子測量和(hé)profiling。黑(hēi)匣子測量的意思是收集由性能計(jì)數(shù)器(qì)(內(nèi)存使用,上(shàng)下文交換,CPU利用等)和(hé)外部檢測工具(通(tōng)量,反映時(shí)間(jiān)等)所顯示的數(shù)據。為(wèi)了profile你(nǐ)的代碼,你(nǐ)編譯代碼的一個(gè)工具版,然後在各種條件下運行(xíng)它,并收集關于執行(xíng)時(shí)間(jiān)和(hé)過程調用頻率的統計(jì)數(shù)據。
測量如果不用于分析的話(huà)就一點用都沒有(yǒu)。測量将不僅告訴你(nǐ)有(yǒu)問題,而且甚至能幫助你(nǐ)找到問題發生(shēng)在哪,但(dàn)它不能告訴你(nǐ)為(wèi)什麽會(huì)有(yǒu)問題。對問題進行(xíng)分析以便你(nǐ)能正确地改正他們。要從根本上(shàng)解決問題而不是停留在表面現象。
當你(nǐ)進行(xíng)改動後,要重新測量。你(nǐ)要知道(dào)你(nǐ)的改動是否有(yǒu)效。改動也可(kě)能會(huì)暴露其他性能問題,測量-分析-改正-再測量的循環就會(huì)重新開(kāi)始。你(nǐ)也必須要有(yǒu)規律地進行(xíng)測量,以便發現性能衰退問題。
9.應該使用單一用戶,單一請(qǐng)求的測試方法。
書(shū)寫ASP和(hé)ISAPI應用程序的一個(gè)通(tōng)病是隻用一個(gè)浏覽器(qì)去測試應用程序。當他們在Internet上(shàng)應用他們的程序時(shí),他們才發現他們的應用程序不能處理(lǐ)高(gāo)負載,并且通(tōng)量和(hé)反應時(shí)間(jiān)另人(rén)可(kě)憐。
用一個(gè)浏覽器(qì)測試是必要的但(dàn)是不夠的。如果浏覽器(qì)反應得(de)不夠快,你(nǐ)就知道(dào)你(nǐ)有(yǒu)麻煩了。但(dàn)即使它在使用一個(gè)浏覽器(qì)時(shí)很(hěn)快,你(nǐ)也不知道(dào)它處理(lǐ)負載的能力如何。如果十幾個(gè)用戶同時(shí)請(qǐng)求會(huì)發生(shēng)什麽事?一百個(gè)呢?你(nǐ)的應用程序能容忍什麽樣的通(tōng)量?它能提供什麽樣的反應時(shí)間(jiān)?在輕載時(shí)這些(xiē)數(shù)字會(huì)怎樣?中等負載呢?重載呢?在多(duō)處理(lǐ)器(qì)機器(qì)上(shàng)你(nǐ)的應用程序會(huì)如何?對你(nǐ)的應用程序進行(xíng)強度測試,這對于找出bugs發現性能問題來(lái)說是基本的。
類似的負載測試考慮适用于所有(yǒu)的服務器(qì)應用程序。
10.不應使用實際環境。
人(rén)們往往隻在幾個(gè)特定的,人(rén)工的環境(如下benchmarks)下調整應用程序。選擇和(hé)實際情況相對應的各種情況,并為(wèi)針對各種操作(zuò)進行(xíng)優化,這一點很(hěn)重要。如果你(nǐ)不這樣做(zuò),你(nǐ)的用戶和(hé)評論家(jiā)一定會(huì)這樣做(zuò),并且他們将依此來(lái)評判你(nǐ)的應用程序的好壞。
重慶中技互聯網信息咨詢有限公司
重慶網站(zhàn)建設事業部官方網:www.zjcoo.com
電(diàn)子商務建站(zhàn)事業部咨詢電(diàn)話(huà):023-67742189
門(mén)戶網站(zhàn)品牌加盟推廣電(diàn)話(huà):023-67742189
7*24小(xiǎo)時(shí)服務電(diàn)話(huà):023-67742189
媒體(tǐ)合作(zuò)電(diàn)話(huà):13883323406
投資合作(zuò)電(diàn)話(huà):13896068183
QQ及郵件地址:446515345@qq.com
企業網站(zhàn)建設解決方案 營銷型網站(zhàn)建設解決方案 行(xíng)業門(mén)戶網站(zhàn)建設解決方案 外貿網站(zhàn)解建設決方案 品牌形象網站(zhàn)建設解決方案 購物商城網站(zhàn)建設解決方案 政府網站(zhàn)建設解決方案 手機網站(zhàn)建設解決方案 教育培訓網站(zhàn)建設解決方案 珠寶高(gāo)端奢飾品網站(zhàn)建設解決方案 房(fáng)地産、地産項目網站(zhàn)建設解決方案 集團、上(shàng)市企業網站(zhàn)建設解決方案 數(shù)碼、電(diàn)子産品網站(zhàn)建設解決方案 美容、化妝品行(xíng)業網站(zhàn)建設解決方案
10年專業互聯網服務經驗 重慶最專業網站(zhàn)團隊 資深行(xíng)業分析策劃 B2C營銷型網站(zhàn)建設領先者 最前沿視(shì)覺設計(jì)、研發能力 時(shí)刻最新技(jì)術(shù)領先研發能力 具有(yǒu)完備的項目管理(lǐ) 完善的售後服務體(tǐ)系 深厚的網絡運營經驗
中技(jì)互聯一直秉承專業、誠信、服務、進取的價值觀,堅持優秀的商業道(dào)德,以用戶最終價值為(wèi)導向,向用戶提供優質産品和(hé)優質服務,從而赢得(de)了用戶的信賴。始終以不懈的努力、更高(gāo)的目标來(lái)要求自己。
主營業務:網站(zhàn)建設 | 重慶網站(zhàn)建設 | 重慶網站(zhàn)設計(jì) | 重慶網站(zhàn)制(zhì)作(zuò) | 重慶網頁設計(jì) | 重慶網站(zhàn)開(kāi)發
CopyrightZJCOO technology Co., LTD. All Rights Reserved.
渝ICP 備11003429号