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