Author Archives: admin

Gperftools性能分析工具使用教程

上一篇博客简单介绍了Linux平台下不同性能分析工具的特点,最后是Google出品的gperftools胜出。今天我们将举一个用gperftools对链接库进行性能分析的例子。

假设我们创建了一个TestGperftools项目,其中包括一个动态链接库模块complex和主程序main,build文件夹用于存放动态链接库和可执行程序,文件结构如下所示。

czl@ubuntu:~/czl/TestGperftools$ tree
.
├── build
├── complex
│   ├── complex.cpp
│   ├── complex.h
│   └── Makefile
├── main
│   ├── main.cpp
│   └── Makefile
└── Makefile

3 directories, 6 files

Continue reading

Linux性能分析工具简介

这半年一直在研究pLink 2的加速策略,了解了相关的性能分析工具,现记录如下。

对软件进行加速的技术路线一般为:首先对代码进行性能分析( performance analysis,也称为 profiling),然后针对性能瓶颈提出优化方案,最后在大数据集上评测加速效果。所以进行性能优化的前提就是准确地测量代码中各个模块的时间消耗。听起来很简单,不就是测量每行代码的运行时间吗,直接用time_t t=clock();不就好了,但是事情并没有那么简单。如果只进行粗粒度的性能分析,比如测量几个大的模块的运行时间,clock()还比较准确,但是如果测量的是运算量比较小的函数调用,而且有大量的小函数调用,clock()就不太准确了。

比如下面的一段代码,我最开始的性能分析方法是在fun1()~fun3()前后添加time_t t=clock(),然后作差求和的。但是3个fun()加起来的时间居然不等于整个while循环的时间,有将近50%的时间不翼而飞了!

while(true) {
	if(fun1()) {
		for(int i=0;i<k;++k) {
			if(flag1) {
				fun2();
			}
		}
	} else {
		fun3();
	}
}

一种可能是while循环以及内部的for循环本身占用了较多的时间,但是好像不太可能呀。还有一种可能是clock()测量有误,time_t只能精确到秒,clock_t只能精确到毫秒,如果一次fun*()的时间太短,导致一次测量几乎为0,那么多次的while和for循环调用累加的时间也几乎为0,导致实际测量到的fun*()时间远小于真实时间。所以自己用代码进行性能分析可能会有较大的误差,最好借助已有的性能分析工具。 Continue reading

2016年终总结

2017农历新年的钟声都已经敲响了,我这2016的年终总结才开始动笔。

2016年,经历了很多,也成长了很多,遇到了很多曾经以为只会出现在电视剧中的场景,令人开始怀疑这个世界。前几天在朋友圈看到一个同学发的状态,觉得很适合作为这篇年终总结的开端。(同学你要是觉得被侵权了,告诉我,我立马删掉:-))

每个家庭的故事都会是一部长篇史诗。曾经总以为很多情节只会出现在电视剧中,现实的生活很是平淡无味,没有任何波澜,偶尔甚至还会抱怨一下自己不是故事的女主角,其不知现实的生活相比于电视剧,往往是有过之而无不及。

今天哥哥来电话了,从“天津”,一个美丽的谎言,一直在继续,还会坚持很久...

奶奶很开心...

——by angel

Continue reading

电动汽车加电站

今天中午和超哥在食堂吃饭的时候聊起了电动汽车加电站的问题,很有意思。

超哥现在开的是一辆电动汽车,他说目前也挺满意的,只要在北京市内开,几乎没问题,充电桩到处都有,马力也足,开起来没有任何噪声。唯一的问题是需要每天充电,去到稍微远一点的京郊可能会电量不足。

然后就讨论到目前电动汽车的瓶颈,主要还是在电池上,一个是续航时间短,另一个是充电时间慢。 Continue reading

香山游记

2016年11月5日,雾霾重度污染,2~18℃。

噩梦,6点多被惊醒,7点起。

洗漱完毕,填写周报和各种评价,8:30吃早餐,9点到达保福寺桥南,看到630就在我前脚走了,等待15分钟上车。

车上昏睡一个小时,10:15到达香山公园,10元门票,10:30正式开始爬山。

singledouble

虽然是雾霾天,游客却熙熙攘攘,大多三两成群,唯独我孤身一人。 Continue reading

最怕空气突然安静

最怕空气突然安静
最怕朋友突然的关心
最怕回忆突然翻滚绞痛着不平息
最怕突然听到你的消息

想念如果会有声音
不愿那是悲伤的哭泣
事到如今终於让自已属於我自已
只剩眼泪还骗不过自己

突然好想你你会在哪里
过的快乐或委屈
突然好想你突然锋利的回忆
突然模糊的眼睛

我们像一首最美丽的歌曲
变成两部悲伤的电影
为什麽你带我走过最难忘的旅行
然後留下最痛的纪念品

我们那麽甜那麽美那麽相信
那麽疯那麽热烈的曾经
为何我们还是要奔向
各自的幸福和遗憾中老去

突然好想你你会在哪里
过的快乐或委屈
突然好想你突然锋利的回忆
突然模糊的眼睛

最怕空气突然安静
最怕朋友突然的关心
最怕回忆突然翻滚绞痛着不平息
最怕突然听到你的消息
最怕此生已经决定自己过
没有你却又突然听到你的消息
Continue reading

C++基本数据类型备忘

今天阅读《C++ Primer, 5e》的第二章,介绍C++的基本内置类型,觉得有一些平时工作容易出错的知识点,现摘录如下:


unsigned char c = -1; // 假设char占8比特,c的值为255

当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。例如,8比特大小的unsigned char可以表示0至255区间内的值,如果我们赋了一个区间以外的值,则实际的结果是该值对256取模后所得的余数。因此,把-1赋给8比特大小的unsigned char所得的结果是255。


signed char c2 = 256; // 假设char占8比特,c2的值是未定义的

当我们赋给带符号类型一个超出它表示范围的值时,结果是未定义的(undefined)。此时,程序可能继续工作、可能崩溃,也可能生成垃圾数据。 Continue reading

随机矩阵及其特征值

随机矩阵是这样一类方阵,其元素为非负实数,且行和或列和为1。如果行和为1,则称为行随机矩阵;如果列和为1,则称为列随机矩阵;如果行和和列和都为1,则称为双随机矩阵。

前面我们介绍的谷歌矩阵HMM中的转移矩阵都属于随机矩阵,所以随机矩阵也称为概率矩阵、转移矩阵、或马尔可夫矩阵。

随机矩阵有一个性质,就是其所有特征值的绝对值小于等于1,且其最大特征值为1。下面通过两种方法证明这个结论。

首先,随机矩阵A肯定有特征值1,即

\begin{equation}A\vec 1=1\times\vec 1\end{equation}

其中的单位向量\vec 1=(\frac{1}{n},...,\frac{1}{n})^T,因为A的行和为1,所以上述等式成立。即1是A的特征值。 Continue reading

马尔可夫聚类算法

马尔可夫聚类算法(The Markov Cluster Algorithm, MCL)是一种快速可扩展的基于图的聚类算法。它的基本思想为:在一个稀疏图G中,如果某个区域A是稠密的(是一个聚类),则在A中随机游走k步,还在A内的概率很大,也就是说,A内的k步路径(k-length path)很多。所以我们可以在图中随机游走k步,如果某个区域连通的概率很大,则该区域是一个聚类。随机游走的下一步只和当前所处节点有关,也就是说这是一个马尔可夫的随机游走过程。

我们用一个例子来演示马尔可夫聚类算法的过程。

mcl-1 Continue reading

隐马尔可夫模型及其应用(2)学习问题&识别问题

上一回介绍了HMM的解码问题,今天我们介绍HMM的学习问题和识别问题,先来看学习问题。


正如上一回结束时所说,HMM的学习问题是:仅已知观测序列\vec y,要估计出模型参数组\vec\lambda=(\mu,A,B),其中\mu为初始概率分布向量,A为转移概率矩阵,B为发射概率矩阵。

算法设计

求解HMM的参数学习问题,就是求解如下的最优化问题:

\begin{equation} P(\vec Y = \vec y|\hat \lambda)=\max\limits_{\vec \lambda} P(\vec Y = \vec y|\vec \lambda)\end{equation}

也就是找一个参数\vec \lambda,使得模型在该参数下最有可能产生当前的观测\vec y。如果使用极大似然法求解,对于似然函数P(\vec Y=\vec y|\vec \lambda)=\sum\limits_{i_1,...,i_T}\mu_{i_1}b_{i_1y_1}a_{i_1i_2}...a_{i_{T-1}i_T}b_{i_Ty_T}而言,这个最大值问题的计算量过大,在实际中是不可能被采用的。为此,人们构造了一个递推算法,使其能相当合理地给出模型参数\vec \lambda的粗略估计。其核心思想是:并不要求备选\vec\lambda使得P(\vec Y=\vec y|\vec \lambda)达到最大或局部极大,而只要求使P(\vec Y=\vec y|\vec \lambda)相当大,从而使计算变为实际可能。 Continue reading