摘要:
有网文称c标准库的rand/random随机数产生函数性能极差。一直信以为真,但从没做过验证。最近因其他因缘,写了些代码专门验证rand/random的性能。结果大出意料,颠覆之前的成见。
结论如下:
1) rand/random性极佳。在64位机器上,其性能大约比简单自增略低30%(32位的自增比64位性能高出1倍以上)!
2) srand/srandom性能极差极差。绝对不能每次调用rand之前都调用srand。这么做不仅没必要,还会极大降低性能,性能只有调用rand的1%!!! 阅读全文
随笔分类 - C/C++
通用高效的c++内存池(特定类型)
2012-06-03 15:35 by zhenjing, 4469 阅读, 收藏, 编辑
摘要:
介绍一最近实现的特定类型的通用高效C++内存池。
特点:
1)基于共享内存; -- 不会因为进程挂掉而丢失数据。
2)快速分配; -- 在内存池接近满时,效率不高。
3)快速回收;-- 常数
4)空间利用率高 -- 利用bit标识内存块使用与否 (《C++设计新思维》的小对象分配器不占用额外空间!!) 阅读全文
工具脚本(网络编码)
2012-05-18 19:56 by zhenjing, 652 阅读, 收藏, 编辑
摘要:
自用的工具脚本:1) 生成结构体网络编码(Ntoh(), Hton() )的perl脚本; 2) 正则表达式测试脚本。 阅读全文
RAII、栈展开和程序终止
2011-07-06 00:11 by zhenjing, 3210 阅读, 收藏, 编辑
摘要:
RAII(资源获取即初始化RAII, Resource Acquisition Is Initialization)是C++编程中很重要的一项技术。其原理是在对象析构函数中释放该对象获取的资源,利用栈展开过程栈上对象的析构函数将被自动调用的保证,从而正确地释放先前获取的资源。RAII只有在栈展开正常执行的前提下才能正常工作。函数调用和正常的C++异常处理流程(异常处于try-catch块)都存在栈展开。应该特别注意的是:在程序运行过程中,RAII可以可靠地正确地释放资源;但当程序非正常终止时,栈展开经常被忽略,从而导致RAII失效。 阅读全文
Gdb调试多进程程序
2011-06-01 13:45 by zhenjing, 26015 阅读, 收藏, 编辑
摘要:
介绍使用gdb调试多进程程序的几种常见办法:方法1:调式多进程最土的办法:attach pid; 方法2: set follow-fork-mode child + main断点; 方法3: set follow-fork-mode child + catch exec; 方法4:info inferiors/inferior inferiors 阅读全文
内存数据的十六进制Print
2011-04-20 09:22 by zhenjing, 4263 阅读, 收藏, 编辑
摘要:
在程序的调试过程中,经常需要输出各种数据,正常情况下使用printf和cout即可实现数据输出。然而在输出二进制数据时,printf和out却有点无能为力。那么如何比较二进制数据是否正确呢?方案一:文件输出。文件可以输入任何数据,但是需要在程序之外比较文件,这对于少量数据并不划算。方案二:实现自定义的十六进制输出函数。当然,也可是八进制,一般而言十六进制更易看懂(习惯)。下面给出一个最近实现的此类函数。该函数可将指定长度任何内存数据以十六进制格式输出。这个程序对32和64位的PC均适用。注意:%x无法正确打印负数,负数总是打印成32bit整型数,64位PC也是如此。#include <s 阅读全文
GCC/G++常见链接错误
2011-04-20 09:21 by zhenjing, 1197 阅读, 收藏, 编辑
摘要:
链接错误的直接表现就是:****符号未定义。几种常见的链接错误如下:缺少*.o文件 ---- 对策:将相应的文件加入Makefile或命令行*.o文件未更新 ---- 对策:删除旧*.o文件重新编译或者依赖于最新的depend来编译(增删文件时确保make depend)。缺少相应的库文件 ---- 对策:将相应的文件加入Makefile或命令行依赖的库文件版本不对或未更新 ---- 对策:重新生成所依赖的库文件库文件的出现顺序不对 ----- 对策:根据库的依赖关系,调整库出现的顺序。原则:只允许先出现的库依赖于后出现的库。其中,第5种错误最难发现。如果发现程序所需的库都已经引入,但仍出现链 阅读全文
[Advance] How to debug a program (下):示例
2011-03-23 13:10 by zhenjing, 1239 阅读, 收藏, 编辑
摘要:
原理:程序=指令+数据。
指令:用户代码(Text)+静态库+动态库。反汇编可得程序指令。
数据:Data -- 已初始化的全局数据,包括常量字符串;BSS -- 未初始化的全局数据;Heap; Stack;Register 阅读全文
[Advance] How to debug a program (上)
2011-03-22 12:16 by zhenjing, 2194 阅读, 收藏, 编辑
摘要:
介绍64位linux系统下的一种高级调试技巧。32位类似,内存分布略有区别。 阅读全文
[转] Real-World Concurrency
2011-03-15 13:37 by zhenjing, 540 阅读, 收藏, 编辑
摘要:
1. Know your cold paths from your hot paths. 弄清楚代码里的热门执行路径和冷门执行路径。
2. Intuition is frequently wrong—be data intensive. 直觉常常是错的,要靠数据说话。
3. Know when—and when not—to break up a lock. 知道什么时候把一个锁拆成多个,并知道什么时候不必这样做。
4. Be wary of readers/writer locks. 警惕读写锁。
5. Consider per-CPU locking. 考虑用每个 CPU 用一个锁。
6. Know when to broadcast—and when to signal. 知道什么时候用单个唤醒,什么时候用广播唤醒。
7. Learn to debug postmortem. 学会验尸
8. Design your systems to be composable. 设计系统(s),使之能相互组合。
9. Don’t use a semaphore where a 阅读全文
[转] Policies/Binary Compatibility Issues With C++
2011-03-15 11:11 by zhenjing, 758 阅读, 收藏, 编辑
摘要:
C/C++ 的二进制兼容性 (binary compatibility)与ABI (application binary interface)关系甚大。到底如何判断一个改动是不是二进制兼容呢?这跟 C++ 的实现方式直接相关,虽然 C++ 标准没有规定 C++ 的 ABI,但是几乎所有主流平台都有明文或事实上的 ABI 标准。C++ ABI 的主要内容:
* 函数参数传递的方式,比如 x86-64 用寄存器来传函数的前 4 个整数参数
* 虚函数的调用方式,通常是 vptr/vtbl 然后用 vtbl[offset] 来调用
* struct 和 class 的内存布局,通过偏移量来访问数据成员
* name mangling
* RTTI 和异常处理的实现(以下本文不考虑异常处理)
C/C++ 通过头文件暴露出动态库的使用方法,这个“使用方法”主要是给编译器看的,编译器会据此生成二进制代码,然后在运行的时候通过装载器(loader)把可执行文件和动态库绑到一起。如何判断一个改动是不是二进制兼容,主要就是看头文件暴露的这份“使 阅读全文
[转] Buffer Overflows and You (下)
2011-03-03 11:59 by zhenjing, 810 阅读, 收藏, 编辑
摘要:
Got root?Gentlemen, we can root it. We have the technology. We have the capability to root yet another poor idiot's server on the int4rw3bs. Steve Austin will be that man. Better than he was before. Better, stronger, faster, errrr...We spent all that time developing a small bit of shellcode. Let 阅读全文
[转] Buffer Overflows and You (上)
2011-03-03 11:48 by zhenjing, 797 阅读, 收藏, 编辑
摘要:
Magical gnomes present: Buffer Overflows and You
Is it the 90's? Are you wondering why your server is running slow? Why it's trying to ping flood some host in California? Why someone else is logged into your machine and you've recently become a prominent porn hosting provider? This site will help you figure it all out. And if you have a time machine, you can probably go back and do it to someone else!
Before continuing, it's important to note that this guide is designed for 64-bit systems. 阅读全文
[C++再学习系列] stl::string与二进制数据
2011-01-30 14:14 by zhenjing, 9536 阅读, 收藏, 编辑
摘要:
C99有很多和string相关的函数,如 strcat,strchr,strcmp,strcpy,strlen,strncat,strncmp,strncpy等。然而使用C++编程时,所有和string相关的操作均可以使用string类的相关接口完成,string提供和原来C接口类似的功能和性能,同时提供更高的安全性。 String类有一个特性:a string of length n must manage a block of memory whose size is at least n + 1。即长度为n的string对象,其内存空间至少为n+1个字符,且最后一个字符为’\0’。不过在进行string操作时,有一点必须牢记:C/C++语言的string是以’\0’结尾的,对不以’\0’结尾的string进行操作容易引发错误,甚至导致内存溢出等crash。 C++的string类,除了用于处理常规string操作外,其本身也可用于存储各种数据,如文件数据。使用者采用string( const char* str, size_type 阅读全文
[C++再学习系列] STL容器删除操作总结
2011-01-30 12:01 by zhenjing, 2803 阅读, 收藏, 编辑
摘要:
由于容器所对应不同的迭代器、指针和引用的失效规则,使得容器的删除操作较为复杂。解决问题的最好方法取决于你是怎样鉴别出哪个对象是要被去掉的,储存它们的容器的类型,和当你删除它们的时候你还想要做什么。 阅读全文
[C++再学习系列] 函数声明与STL容器构造
2011-01-28 10:56 by zhenjing, 1344 阅读, 收藏, 编辑
摘要:
C++有一条通用规则——几乎任何东西都可能被分析成函数声明。如果使用不当,这个规则将引发“声明错误”,将声明被当成函数来解析。这种现象在STL容器的使用中最常见。 阅读全文
[C++再学习系列] 函数模板和类模板
2011-01-25 12:51 by zhenjing, 1289 阅读, 收藏, 编辑
摘要:
函数模板和类模板C++提供类模板和函数模板。函数模板允许重载,而类模板不允许重载(类无重载概念)。类模板可以进行全特化和偏特化,而函数模板仅能够全特化。因此,写一个看似函数模板偏特化的函数模板实际上是在写一个单独的主函数模板!由于函数模板可以重载,因此存在重载决议。但是记住,函数模板特化并不参与重载。只有在某个主模板函数被重载决议选中的前提下,其特化版本才有可能被使用。因此,如果想要将一个主模板特化,同时希望该特化版本能够参与重载决议,那么应该将使用普通函数而不是特化版本。(这是因为普通函数比函数模板优先级更高)如果希望函数模板可以被特化、偏特化,应该使用类模板来封装。类模板可以被偏特化。总结:函数模板不能偏特化只能重载,函数模板的特化并不参与重载决议。这和直觉有点不同。注意:1. 对于模板函数。不能使用默认参数。默认参数仅仅对模板类有效。2. 在编写模板函数的过程中。函数体内所有使用到的类型都必须是已知的(当然对于template中的参数类型。在函数体内也属已经的类型)。就是说不能在函数体内使用新定义的类型。如果使用像迭代器这样的特化类型,需要使用typename 做限定。 阅读全文
[C++再学习系列] 模板函数的自定义点
2011-01-24 12:00 by zhenjing, 1199 阅读, 收藏, 编辑
摘要:
在编写模板时,可以通过一些显示的自定义,对模板参数类型做一些必要的限制: 选择1: 模板直接依赖于类型具有给定名字的合适的成员函数, 则显式要求参数T提供该成员函数. 选择2: 模板依赖于”类型具有给定名字的合适的非成员函数”, 则显式的要求T具有给定名字/签名和语义的非成员函数. 选择3: 模板依赖于”类型已经特化(如果必要)另一个模板”, 则需要被特化的模板提供一个(通常是静态类成员)具有给定名字/签名和语义的函数. 阅读全文
[C++再学习系列] typename和依赖类型
2011-01-21 13:54 by zhenjing, 1364 阅读, 收藏, 编辑
摘要:
template class Widget { ... }; class和typename均可用于声明模板的形式类型参数,但typename能更清楚地表示:T可以是任何类型;不必是一个类。为了避免潜在的模糊解析,编译器要求在依赖形式类型参数的类型名字之前使用typename。这样的类型被称为依赖类型。常见例子如容器迭代器。 阅读全文
[C++再学习系列] 深入new/delete:类域的operator new重载
2011-01-17 11:23 by zhenjing, 3187 阅读, 收藏, 编辑
摘要:
为class 重载 operator new 时必须定义为类的静态函数(默认为static函数)。重载operator new更多的是为了提高程序效率,比如使用静态内存代替动态分配,启用小对象分配器等。但是要正确重载类域的operator new并不容易,有很多规则需要注意:1) 总是成对提供new/delete;2) 如重载operator new一定要同时提供标准形式的new。 阅读全文