頂下!
先下來(lái)慢慢研究,以后用的著,呵呵
@xushiwei
你的測(cè)試代碼對(duì)apr-pool不公平,首先(1)作為服務(wù)器,關(guān)心是長(zhǎng)期運(yùn)行后的性能,而不是開(kāi)始幾個(gè)請(qǐng)求的性能,一個(gè)服務(wù)器可能365天無(wú)間斷服務(wù),而只拿系統(tǒng)啟動(dòng)2分鐘的性能來(lái)衡量1年的性能顯然不合適,而apr-pool開(kāi)始申請(qǐng)內(nèi)存是直接new,釋放的時(shí)候才組織內(nèi)存池結(jié)構(gòu)。(2)對(duì)于集中處理的情況(類似你的測(cè)試代碼),內(nèi)存的申請(qǐng)是從同一個(gè)池中申請(qǐng)的,而不是申請(qǐng)一塊內(nèi)存,就必須先申請(qǐng)一個(gè)池。
你的測(cè)試代碼,(1)是針對(duì)apr-pool性能最差的建池階段 (2)每申請(qǐng)一塊內(nèi)存,反復(fù)的從allocator創(chuàng)建銷毀內(nèi)存池,和實(shí)際的使用不相符
而你的內(nèi)存池,則沒(méi)有建池階段,直接棧中建池,我認(rèn)為用上面寫(xiě)過(guò)apr-pool測(cè)試代碼用來(lái)測(cè)試,才對(duì)apr-pool公平。
其實(shí)我覺(jué)得對(duì)內(nèi)存池做這種性能對(duì)比沒(méi)意義,首先這是變長(zhǎng)內(nèi)存池,不需要考慮釋放,性能對(duì)比也就只是測(cè)試申請(qǐng)階段的性能,而變長(zhǎng)內(nèi)存池都是在已有大內(nèi)存上的指針滑動(dòng),都是常數(shù)步驟內(nèi)完成。因此和算法之間對(duì)比性能不同,完善的內(nèi)存池之間根本就沒(méi)有性能比較的必要。
@創(chuàng)
你的模型是不是和細(xì)分類2中(1)的模型類似啊,直接使用線程不更好嘛。如果是用epoll的話,直接單線程在epoll處wait就好。
以前去你blog上逛過(guò),呵呵,多多交流!
struct, union的sizeof問(wèn)題這個(gè)才是常識(shí)性的問(wèn)題,尤其對(duì)于網(wǎng)絡(luò)間傳輸?shù)臄?shù)據(jù)結(jié)構(gòu),這是必須知道的基礎(chǔ)性問(wèn)題。
@sgsoft
win上實(shí)現(xiàn)了socket上真正的AIO,*inx上基本上都沒(méi)有針對(duì)socket實(shí)現(xiàn)真正的AIO。本文主要針對(duì)linux平臺(tái),其他平臺(tái)不很熟悉,并且沒(méi)機(jī)會(huì)接觸,也無(wú)法寫(xiě)代碼進(jìn)行測(cè)試,因此AIO的模型就沒(méi)涉及。
另詳細(xì)分類2里的模型(5)模擬了AIO的實(shí)現(xiàn),也就是proactor的模擬。
re: 不怕無(wú)知,但怕無(wú)畏 cppexplore 2008-03-21 18:55
是啊 有問(wèn)題就問(wèn)題本身探討 涉及到人身 甚至去猜測(cè)別人的水平 不利于解決問(wèn)題啊 來(lái)來(lái)回回凈扯蛋了
re: PKU-1094 cppexplore 2008-03-21 09:37
不好意思 請(qǐng)關(guān)注私人留言!
re: 不怕無(wú)知,但怕無(wú)畏 cppexplore 2008-03-21 09:19
@飯中淹
牛啊 果然是最好的內(nèi)存copy實(shí)現(xiàn),竟然還實(shí)現(xiàn)了跨平臺(tái)
要是加上inline 或者用包裹宏代替函數(shù)就更完美了 哈哈
re: 不怕無(wú)知,但怕無(wú)畏 cppexplore 2008-03-21 09:11
@Fox
沒(méi)看過(guò)memcpy strcpy庫(kù)函數(shù)實(shí)現(xiàn)的,給出按位處理的想法很正常。就像去寫(xiě)strcpy,檢測(cè)空指針、越界、返回結(jié)果指針就很好了,一定要求他給出類似庫(kù)函數(shù)實(shí)現(xiàn)的高效不太現(xiàn)實(shí),也沒(méi)啥意義,就象研究茴香豆的茴有幾種寫(xiě)法一樣。反正實(shí)際開(kāi)發(fā)中不用,就是虛無(wú)縹緲的想想。
re: 不怕無(wú)知,但怕無(wú)畏 cppexplore 2008-03-21 08:21
呵呵
考察memcpy內(nèi)存地址的字節(jié)對(duì)齊問(wèn)題 對(duì)實(shí)際的開(kāi)發(fā)有啥意義嗎?
@8340
呵呵 不要著急 近期就馬上寫(xiě) 呵呵 各種服務(wù)器網(wǎng)絡(luò)模型和性能對(duì)比 一起常用的網(wǎng)絡(luò)庫(kù) apr_poll libevent ace asio之類的使用 對(duì)比等。多謝關(guān)注啊
@xushiwei
麻煩做下修改再測(cè)試:
void doAprPools1(LogT& log)
{
log.print("===== APR Pools =====\n");
std::PerformanceCounter counter;
for (int i = 0; i < N; ++i)
{
apr_pool_t* alloc;
apr_pool_create(&alloc, m_pool);
int* p = (int*)apr_palloc(alloc, sizeof(int));
apr_pool_destroy(alloc);
}
counter.trace(log);
}
改成
void doAprPools1(LogT& log)
{
int i;
apr_pool_t* alloc;
apr_pool_create(&alloc, m_pool);
for (i = 0; i < N; ++i)
{
int* p = (int*)apr_palloc(alloc, sizeof(int));
}
apr_pool_destroy(alloc);
apr_pool_t* alloc2;
apr_pool_create(&alloc2, m_pool);
log.print("===== APR Pools =====\n");
std::PerformanceCounter counter;
for (i = 0; i < N; ++i)
{
int* p = (int*)apr_palloc(alloc2, sizeof(int));
}
counter.trace(log);
apr_pool_destroy(alloc2);
}
至于線程鎖的使用開(kāi)銷,這里就先不考慮了。“apr_pool也是,顯式構(gòu)造allocator后不調(diào)用apr_allocator_mutex_set就是無(wú)鎖的實(shí)現(xiàn)。 ”
@wk
一般backlog是兩個(gè)隊(duì)列大小的和,比如設(shè)置為5就是兩個(gè)隊(duì)列的長(zhǎng)是5,隊(duì)列滿了,再有連接到來(lái)就拒絕。但是有的系統(tǒng),你設(shè)置為5,實(shí)際隊(duì)列大小可能是10,你設(shè)置為10,隊(duì)列實(shí)際大小可能是20,就是有的系統(tǒng)有個(gè)系數(shù)。
re: 緣由[未登錄](méi) cppexplore 2008-03-19 12:06
莫非又不了了之了?
不錯(cuò)!
c語(yǔ)言的程序里經(jīng)常是遍地的宏 遍地指針的精巧使用
宏還是非常不錯(cuò)的 類似c語(yǔ)言中的模版機(jī)制
內(nèi)核里的經(jīng)典數(shù)據(jù)結(jié)構(gòu)及其算法,象SLIST LIST TAILQ之類的都是宏寫(xiě)的
很簡(jiǎn)單 未初始化的變量行為未定義,未定義就是怎么都可以
就象調(diào)式環(huán)境是true 并不能保證exe是true
在本機(jī)是true 并不能保證另一個(gè)機(jī)器上也是true
re: 放棄Shell,主攻Perl cppexplore 2008-03-18 09:14
呵呵 我也是因?yàn)閟ocket的原因 看的perl 現(xiàn)在服務(wù)器的陪測(cè)程序 都是用perl寫(xiě)的。特適合寫(xiě)陪測(cè)腳本。下面是我以前寫(xiě)的幾個(gè)服務(wù)器的陪測(cè)腳本
http://www.shnenglu.com/CppExplore/archive/2007/12/04/37752.html
re: ACE 5.6版本的編譯 cppexplore 2008-03-18 08:28
不錯(cuò),如此簡(jiǎn)單,
簡(jiǎn)單的不適宜放在首頁(yè)了 呵呵
@苦味酸
c#的問(wèn)題建議去博客園問(wèn),這邊看樣子知道的不多。另有留言給你。
re: CListCtrl 使用技巧 cppexplore 2008-03-17 10:27
@鑄鑄平板
為啥在這里發(fā)廣告呢
這里是c++技術(shù)blog,沒(méi)人買生鐵的。
re: 分析stl function objects模塊 cppexplore 2008-03-13 13:41
這個(gè)要頂!
re: 最近接觸的東西 cppexplore 2008-03-13 08:32
沒(méi)有模版需求的時(shí)候 總也不知道使用它的原因
有需求的時(shí)候 自然就知道為何使用它
呵呵 順其自然
“這里,我提出另外一種比較獨(dú)特的做法,就是......”
呵呵,兄弟啊,我畢業(yè)答辯的時(shí)候,老師就反復(fù)的批評(píng)我們,“我提出.......”,“我發(fā)明......”之類的東西。
文中就是《unix網(wǎng)絡(luò)編程》中的預(yù)派生進(jìn)程阻塞在accept的方式嘛。
并且書(shū)中說(shuō)明這種問(wèn)題有驚群?jiǎn)栴},可以前面加文件鎖或者線程鎖互斥,你文中加的是互斥鎖。現(xiàn)在的linux從2.2.9版本起就不存在驚群?jiǎn)栴}而不需要加鎖了,更好的是2.6內(nèi)核的線程庫(kù)中線程鎖不陷入互斥狀態(tài)的話就不會(huì)陷入內(nèi)核態(tài)了,加不加性能一樣。而win就沒(méi)有這么好的線程鎖。
多進(jìn)程方式編程簡(jiǎn)單,程序健壯性相對(duì)比較好,但是切換開(kāi)銷比較大。現(xiàn)在的更傾向于預(yù)派生線程的方式。
另可以,起多個(gè)多線程的程序,bind不同port,前端部署lvs提供均衡負(fù)載一樣可以達(dá)到更好的多進(jìn)程效果。
php jsp asp asp.net之類的根本不能算是網(wǎng)絡(luò)編程,也就是web編程,不需要多少知識(shí)深度,競(jìng)爭(zhēng)也很激烈。
vc做圖形開(kāi)發(fā)還是非常有前途的,其他的不知道了。
c++ c編程 或者嵌入式都還是轉(zhuǎn)向linux平臺(tái)吧。
re: 閑又閑的很了,忙也真忙死了[未登錄](méi) cppexplore 2008-03-07 08:24
@火夜風(fēng)舞
兄弟真實(shí)在。呵呵 :)
@eXile
呵呵,還沒(méi)用庫(kù)。
是我最近正在梳理網(wǎng)絡(luò)模型。這幾天正在寫(xiě)各種模型的網(wǎng)絡(luò)程序并測(cè)試性能。
等搞完這個(gè)再看各種庫(kù)是如何實(shí)現(xiàn)這些模型以及其性能如何。
說(shuō)錯(cuò)了 呵呵 三次握手在accept前就完成了 從完成隊(duì)列里取而已
第一部分(2)的結(jié)論不太對(duì)。
主線程偵聽(tīng),預(yù)派生的線程處理業(yè)務(wù),這個(gè)稱為模型A吧.
leader/follow這里稱為B.
我服務(wù)器的4核的SMP,linux 2.6內(nèi)核,測(cè)試工具ab,小壓力的測(cè)試不說(shuō)了,都能達(dá)到17000左右,測(cè)試項(xiàng)如下:
ab -c 4000 -n 40000
http://172.24.252.248:5000/
預(yù)派生線程數(shù)量都是4。
壓力測(cè)試的結(jié)果是:
業(yè)務(wù)邏輯簡(jiǎn)單的時(shí)候(僅僅是讀數(shù)據(jù),然后resonse200OK):
B模型多次測(cè)試平均的結(jié)果大約是每秒8500。
而A模型的性能和緩存隊(duì)列的大小有關(guān),當(dāng)緩存大小取500時(shí),和B模型性能相當(dāng)。取1000,測(cè)試的平均結(jié)果大約是每秒9500。取100則降低為6500左右
猜測(cè)原因:linux的pthread_mutex_t既然是非暫停點(diǎn)的實(shí)現(xiàn),那么它的性能一定很好,遠(yuǎn)好于條件鎖、信號(hào)燈等。pthread_cond_t則是暫停點(diǎn)的實(shí)現(xiàn),可能把線程推向睡眠。增大緩存大小,可以有效減少對(duì)pthread_cond_t的系統(tǒng)調(diào)用。
另根據(jù)對(duì)各種模型的測(cè)試,accept的處理速度非常非常的塊,簡(jiǎn)單的業(yè)務(wù)處理時(shí)間也要比accept的處理低一個(gè)數(shù)量級(jí)。因此單一線程處理accept,可以盡快建立三次握手,進(jìn)入緩存隊(duì)列等待。
因此猜測(cè) 如果業(yè)務(wù)為復(fù)雜邏輯(實(shí)際測(cè)試加了4個(gè)循環(huán)相加,一句打印的log)的話,模型B的性能將進(jìn)一步下降。增大業(yè)務(wù)處理復(fù)雜度后的結(jié)果果然如此,模型B的處理降低為6500左右,而模型A在1000的緩存下,每秒的處理能力還是9500左右。
頂 不錯(cuò)
內(nèi)存申請(qǐng)針對(duì)線程內(nèi)還是跨線程 決定是否采用加鎖策略,為了差異化這種處理,在內(nèi)存池上進(jìn)行進(jìn)一步的封裝 不錯(cuò)!
@陳子文
:)
轉(zhuǎn)載請(qǐng)著名下 多多交流!
上面的語(yǔ)句外面都是foreach(ch in str){}。
hash表的數(shù)量 應(yīng)該不是影響hash的因素吧 想不出來(lái)原因。貌似一般都把hash表的桶數(shù)量設(shè)置的很大,是實(shí)際使用到的3倍多。
java里的hash是乘以31的:hash=hash<<5-hash+ch。
據(jù)說(shuō)就英文而言,乘以33的是最優(yōu)的:hash=hash<<5+hash+ch,這個(gè)也是apache stl等一大堆著名項(xiàng)目或庫(kù)的hash方式。
特定應(yīng)用而言,還是要根據(jù)特定的數(shù)據(jù),設(shè)計(jì)最優(yōu)的hash函數(shù)。
空間有毒!!!!大家小心
@浪跡天涯
如果是什么計(jì)數(shù)器卡著了,也請(qǐng)修改正常。
非常不錯(cuò)!這6個(gè)原則概括的還真是精辟!
非常不錯(cuò)!這6個(gè)原則概括的還真是精辟!
暈倒..........................
問(wèn)題的關(guān)鍵不在UserAlloc,而是details::PODptr<size_type> 。除非你想在內(nèi)存池之上實(shí)現(xiàn)這個(gè)內(nèi)存池的UserAlloc(到底是先有雞還是先有蛋......),即便這樣,當(dāng)前的object_pool析構(gòu)最少也要付出o(n)的代價(jià)。
@eXile
:)
“從收到一個(gè)包,到對(duì)這個(gè)包的處理完畢,則可視為內(nèi)存的一個(gè)周期。”,這時(shí)候析構(gòu)object_pool不恰當(dāng),因?yàn)橐院筮€會(huì)收到包,內(nèi)存還可循環(huán)被使用,這里還是應(yīng)該調(diào)用destroy,而它的時(shí)間復(fù)雜度o(n),導(dǎo)致了真是不太適合使用。析構(gòu)object_pool更不可取,時(shí)間復(fù)雜度不說(shuō),還有內(nèi)存的再次申請(qǐng),背離了內(nèi)存池的初衷。
@eXile
暈倒 在boost/pool/detail/pool_construct.inc里
只關(guān)注hpp去了
可以調(diào)用任意的構(gòu)造函數(shù)
多謝指正!正文中現(xiàn)已標(biāo)明。
另:boost/pool下的6個(gè)hpp文件我是挨個(gè)讀過(guò)了。detail下的都很簡(jiǎn)單,5個(gè)hpp,singleton.hpp有效行數(shù)就10幾行,沒(méi)看,想當(dāng)然了下。mutex和guard在讀singleton_pool.hpp的時(shí)候看了下linux下的mutex,順便還測(cè)試了下,gcd_lcm的兩個(gè)也很簡(jiǎn)單,沒(méi)看,估計(jì)大約是2者求最小值的功能。
我一貫認(rèn)為,明白原理,知道如何使用就好,深入具體細(xì)節(jié)就是浪費(fèi)腦細(xì)胞,如果你要實(shí)現(xiàn)一個(gè)當(dāng)然例外。
@Enoch
呵呵,借用一句流行話:您的回帖是我繼續(xù)的最大動(dòng)力。
謝謝
@空明流轉(zhuǎn)
這個(gè)現(xiàn)在還是只能停留在美好的展望階段,不過(guò)這一天的到來(lái)不遠(yuǎn)了。
@CornerZhang
呵呵,apache很成功,apr_pool自然不會(huì)差。
@eXile
AutoFreeAlloc的發(fā)展方向應(yīng)該就是apr_pool。apr_pool已經(jīng)把變長(zhǎng)的內(nèi)存池發(fā)展到極致,當(dāng)然這是當(dāng)前看到的,或許以后有內(nèi)存池會(huì)把變長(zhǎng)內(nèi)存池推到一個(gè)新的高度。:)
支持多線程的內(nèi)存池都是從單線程加鎖機(jī)制實(shí)現(xiàn)的,都提供無(wú)鎖的實(shí)現(xiàn)。apr_pool也是,顯式構(gòu)造allocator后不調(diào)用apr_allocator_mutex_set就是無(wú)鎖的實(shí)現(xiàn)。
后面的boost和loki的無(wú)鎖和有鎖的實(shí)現(xiàn)區(qū)別更是明顯。
@空明流轉(zhuǎn)
歡迎光顧本帖。:)
隨意起的名字,沒(méi)啥含義,再下個(gè)定義就咬文嚼字了,呵呵。
當(dāng)然系統(tǒng)的核心是業(yè)務(wù)。系統(tǒng)設(shè)計(jì)可以說(shuō)有技術(shù)層面的有業(yè)務(wù)層面的。
我主要想寫(xiě)點(diǎn)技術(shù)層面的東西,分享一下個(gè)人的感想。一大堆亂七八糟的東西,想不住什么共性來(lái),就隨意起了這個(gè)名字。
re: 緣由[未登錄](méi) cppexplore 2008-02-12 15:04
哈哈 。。。。。。。。。。。。。。。。。
開(kāi)業(yè)大吉啊!!
原來(lái)是本blog的開(kāi)山文章啊
使勁頂啊
有空來(lái)我blog看看,多多交流!!
先頂下 慢慢看
以前看astrisk的源碼(c語(yǔ)言實(shí)現(xiàn)) 覺(jué)得它的架構(gòu)就完美了 所有模塊都可以動(dòng)態(tài)加載 卸載,所有接口都可以動(dòng)態(tài)注冊(cè) 注銷。
貌似ace里也有組件配置框架,還沒(méi)研究過(guò)。
文中的poco的支持 很有吸引力啊
re: 濫用ini配置文件造成崩潰[未登錄](méi) cppexplore 2008-01-29 14:45
為啥就不用內(nèi)存數(shù)據(jù)庫(kù)呢
意義不大
首先 無(wú)論是win下還是linux下 都有很出色的內(nèi)存檢測(cè)工具。這些工具已經(jīng)成為測(cè)試程序的必須,而不是可選。
其次 不論是內(nèi)存檢測(cè)工具 還是文中所述方法 都只能檢測(cè)嚴(yán)格的內(nèi)存泄漏,比如base *a=new A(); base *b=new B(); a=b;則對(duì)原a的內(nèi)存控制完全失去,此為內(nèi)存泄漏。完全的內(nèi)存檢測(cè) 還要配合 完善的log機(jī)制 交互式查看系統(tǒng)信息等附加功能
最后,小trick,又是轉(zhuǎn)貼,和樓上意見(jiàn)一樣,就不要放首頁(yè)了。