如何精确测量一段代码的执行时间
最近在工作中遇到了需要精确测量一段C代码执行时间的需求,大家给出的方案有以下三种:
gettimeofday(2)rdtsc/rdtscpclock_gettime(2)
下面我们就逐一介绍下这三种方案的用法和限制,主要的关注点是准确性、精度和调用成本,讨论环境是运行在Intel x86上的Linux x86_64系统,内核的版本号高于2.6.32。
gettimeofday(2)
首先是gettimeofday(2),函数原型如下:
1 |
|
最近在工作中遇到了需要精确测量一段C代码执行时间的需求,大家给出的方案有以下三种:
gettimeofday(2)rdtsc/rdtscpclock_gettime(2)下面我们就逐一介绍下这三种方案的用法和限制,主要的关注点是准确性、精度和调用成本,讨论环境是运行在Intel x86上的Linux x86_64系统,内核的版本号高于2.6.32。
首先是gettimeofday(2),函数原型如下:
1 |
|
前几天实验室的群里扔出了这样一个问题:TCP连接建立的三次握手过程可以携带数据吗?突然发现自己还真不清楚这个问题,平日里用tcpdump或者Wireshark抓包时,从来没留意过第三次握手的ACK包有没有数据。于是赶紧用nc配合tcpdump抓了几次包想检验一下。但是经过了多次实验,确实都发现第三次握手的包没有其它数据(后文解释)。后来的探究中发现这个过程有问题,遂整理探究过程和结论汇成本文,以供后来者参考。
先来张三次握手的图(下面这张图来自网络,若侵犯了作者权利,请联系我删除):

RFC793文档里带有SYN标志的过程包是不可以携带数据的,也就是说三次握手的前两次是不可以携带数据的(逻辑上看,连接还没建立,携带数据好像也有点说不过去)。重点就是第三次握手可不可以携带数据。
先说结论:TCP协议建立连接的三次握手过程中的第三次握手允许携带数据。
Tair是一个高性能、分布式、可扩展、高可靠的NoSQL存储系统。本文基于Tair v3.1.2.43版本,探究其mdb存储引擎的实现。
Tair目前有mdb、ldb和rdb等存储引擎。其中mdb是Tair最早的一款内存型产品,也是在公司内部应用最广泛的集中式缓存。特别适用容量小(一般在M级别,50G之内),读写QPS高(万级别)的应用场景。由于是内存型产品,因此无法保证数据的安全性,对数据安全有要求的应用建议在后端加持久化数据源(例如MySQL)。本文接下来详细讨论Tair mdb存储引擎的实现。
Tair的存储引擎接口是src\storage\storage_manager.hpp里的虚基类storage_manager。所有的Tair存储引擎均继承实现了storage_manager这个虚基类。src\dataserver\tair_manager.cpp文件中的tair_manager::initialize函数根据配置文件中storage_engine的设置初始化相应的存储引擎。


最近一直在忙毕设的事情,博客都快被遗忘了。最近正好在研究sigslot库,索性晚上写点源码分析的水文充充数。
言归正传,sigslot是一个用标准C++语法实现的信号与槽机制的函数库,类型和线程安全。提到信号与槽机制,恐怕最容易想到的就是大名鼎鼎的Qt所支持的对象之间通信的模式吧。不过这里的信号与槽虽然在概念上等价与Qt所实现的信号与槽,但是采用的仅仅是标准C++语法,不像Qt采用了扩展C++语言的方式(Qt需要使用moc工具对代码预处理之后,才能由标准的C++编译器进行编译)。
众所周知,C++是一门特性众多的语言,其支持多种编程范式。虽然C++在一定程度上支持OOP编程,但是C++这种“静态消息机制”的语言一直没有实现对象级别的delegate机制,而C++之父Bjarne主张的“库扩展胜于语言扩展”的做法使得各种解决方案层出不穷。除了信号与槽机制,C++11正式加入的std:bind/std::function组合也提供了优秀的解决方案。这里所说的信号与槽机制也是一种对象间通信的机制,具体的讨论也可以看看sigslot相关介绍中的内容。
sigslot主页: http://sigslot.sourceforge.net
sigslot文档: http://sigslot.sourceforge.net/sigslot.pdf
sigslot库的用法文档中已然很明了了,所以在这里就不赘述了。接下来我们看看这个库的实现。源码分析的方法有很多种,具体到库代码的分析的方法,我喜欢的是先研究库的功能,直到能写出一个demo程序为止。研究一个库的前提是你得会用它,熟悉它的接口。读完文档,很容易就写出了下面的测试代码: