//blog.chinaunix.net/space.php?uid=17299695
以前对cache的学习都是基于书本上的一些理论知识,比如三种映射方式等等。实际编程中虽然意识到系统缓存对IO的影响,但是还没有能够很好的感受到cache对性能的影响。问题起源于一个对于25G文件的处理,显然内存是远远不够的,只能先进行分块。分块后认识到计算各个块的过程是相互独立的,不需要互斥锁。而且机器是8核处理器。于是乎萌生了一个想法,想通过多线程并行执行来提升程序执行效率,缩短算法执行时间。
有了这个想法,我首先写了一个双线程程序,两个线程分别把全局变量cx1和cx2由0加到900000000。运行程序,我确定了通过pthread库与linux的协作,系统把这两个线程调度到两个核上运行。这正是我所期望的。首先我先串行执行两个线程,用时4.8s。
当我满怀信心地认为双线程版本会用时2秒多时,令我吃惊的是,并行版本的程序的运行时间居然是串行版本的2倍!
为了查明原因,我分析是不是大多时间都花在调度上。为了防止线程在不同的cpu上切换(实际上linux的算法也是依这个目的实现以减少开销,即所谓线程的软亲和),我使用了cpu硬亲和的技术,强制两个线程在0和1号cpu上运行。发现时间并没有减少,故排除这个原因。经过上网发问,找到了问题根源:
一个网友说全局变量cx1和cx2不定是完全无关的。它们的地址仅相差4个字节,在cache映射中会被映射到一个块中。对cx1或cx2的写都会使该块变脏,时间就消耗在缓存与内存之间的交换上了(cpu需要把脏数据写回主存)。为了证实这个观点,我将两个变量中间插入了其他一些整型变量。使得他们的地址差为64节。运行程序,速度大幅提升,用了2秒多,符合预先估计。
在网上搜到一篇帖子linux cache机制(原文地址:
http: //www.cnblogs.com/liloke/archive/2011/11/20/2255737.html ),在第4部分伪共享的讨论中用一个例子对我上述问题的原因进行了详细的说明。
原来要写出高性能程序,不得不考虑cache啊! :)
阅读(1421) | 评论(0) | 转发(0) |