re: 发布我的开源cache库ccache cppexplore 2008-03-24 12:32
顶下!
先下来慢慢研究,以后用的着,呵呵
re: 【原创】系统设计之 内存管理(一) cppexplore 2008-03-24 12:28
@xushiwei
你的测试代码对apr-pool不公平,首先(1)作为服务器,关心是长期运行后的性能,而不是开始几个请求的性能,一个服务器可能365天无间断服务,而只拿系统启动2分钟的性能来衡量1年的性能显然不合适,而apr-pool开始申请内存是直接new,释放的时候才组织内存池结构。(2)对于集中处理的情况(类似你的测试代码),内存的申请是从同一个池中申请的,而不是申请一块内存,就必须先申请一个池。
你的测试代码,(1)是针对apr-pool性能最差的建池阶段 (2)每申请一块内存,反复的从allocator创建销毁内存池,和实际的使用不相符
而你的内存池,则没有建池阶段,直接栈中建池,我认为用上面写过apr-pool测试代码用来测试,才对apr-pool公平。
其实我觉得对内存池做这种性能对比没意义,首先这是变长内存池,不需要考虑释放,性能对比也就只是测试申请阶段的性能,而变长内存池都是在已有大内存上的指针滑动,都是常数步骤内完成。因此和算法之间对比性能不同,完善的内存池之间根本就没有性能比较的必要。
re: 【原创】系统设计之 网络模型(二) cppexplore 2008-03-24 12:16
@创
你的模型是不是和细分类2中(1)的模型类似啊,直接使用线程不更好嘛。如果是用epoll的话,直接单线程在epoll处wait就好。
以前去你blog上逛过,呵呵,多多交流!
re: 不怕无知,但怕无畏[未登录] CppExplore 2008-03-23 20:42
struct, union的sizeof问题这个才是常识性的问题,尤其对于网络间传输的数据结构,这是必须知道的基础性问题。
re: 【原创】系统设计之 网络模型(二) cppexplore 2008-03-21 22:05
@sgsoft
win上实现了socket上真正的AIO,*inx上基本上都没有针对socket实现真正的AIO。本文主要针对linux平台,其他平台不很熟悉,并且没机会接触,也无法写代码进行测试,因此AIO的模型就没涉及。
另详细分类2里的模型(5)模拟了AIO的实现,也就是proactor的模拟。
re: 不怕无知,但怕无畏 cppexplore 2008-03-21 18:55
是啊 有问题就问题本身探讨 涉及到人身 甚至去猜测别人的水平 不利于解决问题啊 来来回回净扯蛋了
re: PKU-1094 cppexplore 2008-03-21 09:37
不好意思 请关注私人留言!
re: 不怕无知,但怕无畏 cppexplore 2008-03-21 09:19
@饭中淹
牛啊 果然是最好的内存copy实现,竟然还实现了跨平台
要是加上inline 或者用包裹宏代替函数就更完美了 哈哈
re: 不怕无知,但怕无畏 cppexplore 2008-03-21 09:11
@Fox
没看过memcpy strcpy库函数实现的,给出按位处理的想法很正常。就像去写strcpy,检测空指针、越界、返回结果指针就很好了,一定要求他给出类似库函数实现的高效不太现实,也没啥意义,就象研究茴香豆的茴有几种写法一样。反正实际开发中不用,就是虚无缥缈的想想。
re: 不怕无知,但怕无畏 cppexplore 2008-03-21 08:21
呵呵
考察memcpy内存地址的字节对齐问题 对实际的开发有啥意义吗?
re: 系统设计系列文章 计划提纲[未登录] CppExplore 2008-03-19 18:54
@8340
呵呵 不要着急 近期就马上写 呵呵 各种服务器网络模型和性能对比 一起常用的网络库 apr_poll libevent ace asio之类的使用 对比等。多谢关注啊
re: 【原创】系统设计之 内存管理(一) cppexplore 2008-03-19 17:34
@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也是,显式构造allocator后不调用apr_allocator_mutex_set就是无锁的实现。 ”
@wk
一般backlog是两个队列大小的和,比如设置为5就是两个队列的长是5,队列满了,再有连接到来就拒绝。但是有的系统,你设置为5,实际队列大小可能是10,你设置为10,队列实际大小可能是20,就是有的系统有个系数。
re: 缘由[未登录] cppexplore 2008-03-19 12:06
莫非又不了了之了?
re: 代码自动生成-宏带来的奇技淫巧[未登录] cppexplore 2008-03-19 11:31
不错!
c语言的程序里经常是遍地的宏 遍地指针的精巧使用
宏还是非常不错的 类似c语言中的模版机制
内核里的经典数据结构及其算法,象SLIST LIST TAILQ之类的都是宏写的
很简单 未初始化的变量行为未定义,未定义就是怎么都可以
就象调式环境是true 并不能保证exe是true
在本机是true 并不能保证另一个机器上也是true
re: 放弃Shell,主攻Perl cppexplore 2008-03-18 09:14
呵呵 我也是因为socket的原因 看的perl 现在服务器的陪测程序 都是用perl写的。特适合写陪测脚本。下面是我以前写的几个服务器的陪测脚本
http://www.cppblog.com/CppExplore/archive/2007/12/04/37752.html
re: ACE 5.6版本的编译 cppexplore 2008-03-18 08:28
不错,如此简单,
简单的不适宜放在首页了 呵呵
@苦味酸
c#的问题建议去博客园问,这边看样子知道的不多。另有留言给你。
re: CListCtrl 使用技巧 cppexplore 2008-03-17 10:27
@铸铸平板
为啥在这里发广告呢
这里是c++技术blog,没人买生铁的。
re: 分析stl function objects模块 cppexplore 2008-03-13 13:41
这个要顶!
re: 最近接触的东西 cppexplore 2008-03-13 08:32
没有模版需求的时候 总也不知道使用它的原因
有需求的时候 自然就知道为何使用它
呵呵 顺其自然
re: 多进程服务端实现-共享socket[未登录] cppexplore 2008-03-10 14:42
“这里,我提出另外一种比较独特的做法,就是......”
呵呵,兄弟啊,我毕业答辩的时候,老师就反复的批评我们,“我提出.......”,“我发明......”之类的东西。
文中就是《unix网络编程》中的预派生进程阻塞在accept的方式嘛。
并且书中说明这种问题有惊群问题,可以前面加文件锁或者线程锁互斥,你文中加的是互斥锁。现在的linux从2.2.9版本起就不存在惊群问题而不需要加锁了,更好的是2.6内核的线程库中线程锁不陷入互斥状态的话就不会陷入内核态了,加不加性能一样。而win就没有这么好的线程锁。
多进程方式编程简单,程序健壮性相对比较好,但是切换开销比较大。现在的更倾向于预派生线程的方式。
另可以,起多个多线程的程序,bind不同port,前端部署lvs提供均衡负载一样可以达到更好的多进程效果。
re: 网络和软件相通吗?[未登录] CppExplore 2008-03-08 10:38
php jsp asp asp.net之类的根本不能算是网络编程,也就是web编程,不需要多少知识深度,竞争也很激烈。
vc做图形开发还是非常有前途的,其他的不知道了。
c++ c编程 或者嵌入式都还是转向linux平台吧。
re: 闲又闲的很了,忙也真忙死了[未登录] cppexplore 2008-03-07 08:24
@火夜风舞
兄弟真实在。呵呵 :)
re: 高性能服务器的多线程策略[未登录] cppexplore 2008-03-07 08:16
@eXile
呵呵,还没用库。
是我最近正在梳理网络模型。这几天正在写各种模型的网络程序并测试性能。
等搞完这个再看各种库是如何实现这些模型以及其性能如何。
re: 高性能服务器的多线程策略[未登录] cppexplore 2008-03-06 15:14
说错了 呵呵 三次握手在accept前就完成了 从完成队列里取而已
re: 高性能服务器的多线程策略[未登录] cppexplore 2008-03-06 14:42
第一部分(2)的结论不太对。
主线程侦听,预派生的线程处理业务,这个称为模型A吧.
leader/follow这里称为B.
我服务器的4核的SMP,linux 2.6内核,测试工具ab,小压力的测试不说了,都能达到17000左右,测试项如下:
ab -c 4000 -n 40000
http://172.24.252.248:5000/
预派生线程数量都是4。
压力测试的结果是:
业务逻辑简单的时候(仅仅是读数据,然后resonse200OK):
B模型多次测试平均的结果大约是每秒8500。
而A模型的性能和缓存队列的大小有关,当缓存大小取500时,和B模型性能相当。取1000,测试的平均结果大约是每秒9500。取100则降低为6500左右
猜测原因:linux的pthread_mutex_t既然是非暂停点的实现,那么它的性能一定很好,远好于条件锁、信号灯等。pthread_cond_t则是暂停点的实现,可能把线程推向睡眠。增大缓存大小,可以有效减少对pthread_cond_t的系统调用。
另根据对各种模型的测试,accept的处理速度非常非常的块,简单的业务处理时间也要比accept的处理低一个数量级。因此单一线程处理accept,可以尽快建立三次握手,进入缓存队列等待。
因此猜测 如果业务为复杂逻辑(实际测试加了4个循环相加,一句打印的log)的话,模型B的性能将进一步下降。增大业务处理复杂度后的结果果然如此,模型B的处理降低为6500左右,而模型A在1000的缓存下,每秒的处理能力还是9500左右。
re: 高性能服务器的多线程策略[未登录] cppexplore 2008-03-06 08:30
顶 不错
内存申请针对线程内还是跨线程 决定是否采用加锁策略,为了差异化这种处理,在内存池上进行进一步的封装 不错!
re: 【原创】系统设计之 线程漫谈[未登录] cppexplore 2008-03-05 12:55
@陈子文
:)
转载请著名下 多多交流!
re: 关于哈希表——一个常见的谬误 cppexplore 2008-03-05 08:56
上面的语句外面都是foreach(ch in str){}。
hash表的数量 应该不是影响hash的因素吧 想不出来原因。貌似一般都把hash表的桶数量设置的很大,是实际使用到的3倍多。
re: 关于哈希表——一个常见的谬误[未登录] cppexplore 2008-03-05 08:46
java里的hash是乘以31的:hash=hash<<5-hash+ch。
据说就英文而言,乘以33的是最优的:hash=hash<<5+hash+ch,这个也是apache stl等一大堆著名项目或库的hash方式。
特定应用而言,还是要根据特定的数据,设计最优的hash函数。
re: 再谈sizeof()的问题[未登录] CppExplore 2008-03-01 12:26
空间有毒!!!!大家小心
@浪迹天涯
如果是什么计数器卡着了,也请修改正常。
re: 【原创】系统设计之 内存管理(三)[未登录] cppexplore 2008-02-21 11:52
晕倒..........................
re: 【原创】系统设计之 内存管理(三)[未登录] cppexplore 2008-02-21 11:28
问题的关键不在UserAlloc,而是details::PODptr<size_type> 。除非你想在内存池之上实现这个内存池的UserAlloc(到底是先有鸡还是先有蛋......),即便这样,当前的object_pool析构最少也要付出o(n)的代价。
re: 【原创】系统设计之 内存管理(三)[未登录] cppexplore 2008-02-21 11:06
@eXile
:)
“从收到一个包,到对这个包的处理完毕,则可视为内存的一个周期。”,这时候析构object_pool不恰当,因为以后还会收到包,内存还可循环被使用,这里还是应该调用destroy,而它的时间复杂度o(n),导致了真是不太适合使用。析构object_pool更不可取,时间复杂度不说,还有内存的再次申请,背离了内存池的初衷。
re: 【原创】系统设计之 内存管理(三) cppexplore 2008-02-21 10:29
@eXile
晕倒 在boost/pool/detail/pool_construct.inc里
只关注hpp去了
可以调用任意的构造函数
多谢指正!正文中现已标明。
re: 【原创】系统设计之 内存管理(三) cppexplore 2008-02-21 09:08
另:boost/pool下的6个hpp文件我是挨个读过了。detail下的都很简单,5个hpp,singleton.hpp有效行数就10几行,没看,想当然了下。mutex和guard在读singleton_pool.hpp的时候看了下linux下的mutex,顺便还测试了下,gcd_lcm的两个也很简单,没看,估计大约是2者求最小值的功能。
我一贯认为,明白原理,知道如何使用就好,深入具体细节就是浪费脑细胞,如果你要实现一个当然例外。
re: 软件渲染器的项目已经在SF.NET上了[未登录] CppExplore 2008-02-20 20:17
本站n多人搞图形啊
re: 【原创】系统设计之 内存管理(二) cppexplore 2008-02-20 08:43
@Enoch
呵呵,借用一句流行话:您的回帖是我继续的最大动力。
谢谢
re: 【原创】系统设计之 内存管理[未登录] cppexplore 2008-02-19 15:59
@空明流转
这个现在还是只能停留在美好的展望阶段,不过这一天的到来不远了。
re: 【原创】系统设计之 内存管理[未登录] CppExplore 2008-02-18 20:11
@CornerZhang
呵呵,apache很成功,apr_pool自然不会差。
@eXile
AutoFreeAlloc的发展方向应该就是apr_pool。apr_pool已经把变长的内存池发展到极致,当然这是当前看到的,或许以后有内存池会把变长内存池推到一个新的高度。:)
支持多线程的内存池都是从单线程加锁机制实现的,都提供无锁的实现。apr_pool也是,显式构造allocator后不调用apr_allocator_mutex_set就是无锁的实现。
后面的boost和loki的无锁和有锁的实现区别更是明显。
re: 系统设计系列文章 计划提纲[未登录] cppexplore 2008-02-15 13:47
@空明流转
欢迎光顾本帖。:)
随意起的名字,没啥含义,再下个定义就咬文嚼字了,呵呵。
当然系统的核心是业务。系统设计可以说有技术层面的有业务层面的。
我主要想写点技术层面的东西,分享一下个人的感想。一大堆乱七八糟的东西,想不住什么共性来,就随意起了这个名字。
re: 缘由[未登录] cppexplore 2008-02-12 15:04
哈哈 。。。。。。。。。。。。。。。。。
开业大吉啊!!
原来是本blog的开山文章啊
使劲顶啊
有空来我blog看看,多多交流!!
先顶下 慢慢看
以前看astrisk的源码(c语言实现) 觉得它的架构就完美了 所有模块都可以动态加载 卸载,所有接口都可以动态注册 注销。
貌似ace里也有组件配置框架,还没研究过。
文中的poco的支持 很有吸引力啊
re: 滥用ini配置文件造成崩溃[未登录] cppexplore 2008-01-29 14:45
为啥就不用内存数据库呢
re: (转贴)C/C++程序内存泄漏检测[未登录] cppexplore 2008-01-22 11:04
意义不大
首先 无论是win下还是linux下 都有很出色的内存检测工具。这些工具已经成为测试程序的必须,而不是可选。
其次 不论是内存检测工具 还是文中所述方法 都只能检测严格的内存泄漏,比如base *a=new A(); base *b=new B(); a=b;则对原a的内存控制完全失去,此为内存泄漏。完全的内存检测 还要配合 完善的log机制 交互式查看系统信息等附加功能
最后,小trick,又是转贴,和楼上意见一样,就不要放首页了。