open party上和大家交流的一个例子,通过这里例子说明了大规模数据处理的深远意义
来源:互联网 发布:新郎礼服 知乎 编辑:程序博客网 时间:2024/04/30 18:55
for(;;)
{
void* buffer = malloc(SIZE);
memset(buffer,SIZE);
process(buffer)
free buffer;
}
这是一位实习生(我曾带过10+位实习生,因此见多识广)的伪代码,原本这个SIZE很小,估计是存放URL用的,定义为512字节,后来由于某种原因,扩大到了1M,从512字节扩大到了1M,速度变慢很多。为什么呢?这位同学无法解释,但我让他继续探索,找到真正的原因。
我让他从这样几个方面入手,
(1)首先分析一些主要花费时间的代码,结果发现是memset这一段从512到1M后耗费时间增多,而且增多并不是线性的,我让他先看一下glibc的memset源代码,如下:
#if defined _LIBC || defined STDC_HEADERS || defined USG
# include <string.h>
# define flood memset
#else
static void flood (__ptr_t, int, __malloc_size_t);
static void
flood (ptr, val, size)
__ptr_t ptr;
int val;
__malloc_size_t size;
{
char *cp = ptr;
while (size--)
*cp++ = val;
}
#endif
由此可知memset是每字节每字节的赋值的,这并不是机器喜欢的方式,机器希望的是在4字节对齐的位置上进行操作(32位机器,64位机器喜欢8字节对齐),一次读取32位(4个字节)。因此memset完全可以自己实现一个一次性写4个字节的代码。
(2)接下来需要探索的是malloc,事实上linux内存分配有两种,brk,mmap,前者分配128k以内的内存,后者分配128k以上的内存,在改成1M后,
void* buffer = malloc(SIZE);
这一段是很快的,因为只是分配了虚存,并没有载入内存,可以查看/proc/pid/statm,考察内存分配,memset操作前后的变化。
而memset,就需要进行实际的内存分配,缺页中断,加载TLB等等。
而brk分配的内存是glibc管理的内存,分配很快,释放也方便(很多时候其实并不释放)。因此512字节是,使用的brk分配(效率很高),而变成1M后,使用mmap分配(加上memset的低效)因此效率要低很多。
(3) 这段代码如果改成,效果等价性能也会大幅度提升。
void* buffer = malloc(SIZE);
for(;;)
{
memset(buffer,SIZE);
process(buffer)
}
free buffer;
(4)最后需要质疑的是为什么需要开辟1M大小的空间,是否通过了验证,这样做是否有必要,实际情况是怎样的,memset是否需要,是否可以通过什么其他方法来避免这种计算。
由此可见,很多问题,不好的编码习惯,对机器理解的不够透彻是很难再一般的工作中发现,必须在大规模数据处理的实践场合(处理数据量足够大),才能体现出来,因此大规模数据处理技术是软件、硬件相结合的技术,而且不仅仅是技术上的问题还包括了业务上的问题,废代码,废计算应该去掉,不合理的计算应该变得合理。
- open party上和大家交流的一个例子,通过这里例子说明了大规模数据处理的深远意义
- 在网上找了一个SqlMembershipProvider 的例子,今天在这里给大家贴出来
- window.open的例子和使用方法以及参数说明
- window.open的例子和使用方法以及参数说明
- window.open的例子和使用方法以及参数说明
- window.open的例子和使用方法以及参数说明
- window.open的例子和使用方法以及参数说明
- window.open的例子和使用方法以及参数说明
- 通过一个有趣的例子说明线程的工作机制
- 我们通过下面这个天气数据处理的例子来说明Hadoop的运行原理.
- 基因检测深远的意义
- 通过一个小例子来说明ajax和WebService服务的使用
- 自定义View的一个例子(这里使用了使用了自定义Button)
- 一个例子说明C语言和Java的区别
- 上周末没事写了一个UDP的例子 大家感兴趣的可以参考一下
- MapReduce: 大规模集群上的简化数据处理
- 通过一个例子来解释startService和bindService的区别
- 说明JavaScript 函数间按值传参的一个例子
- PIVOT & UNPIVOT
- 商业MIS系统中成本核算方式的选择
- 初来乍到
- 基于WinCE的嵌入式系统注册表的研究
- 安装包制作 InstallShield
- open party上和大家交流的一个例子,通过这里例子说明了大规模数据处理的深远意义
- AAC的各种规格
- Sql Server 2005 行转列的实现
- 彼岸花
- 关注:小产权房如何妥善处理
- 解决给定义的整型数据输入字符时出现死循环的问题
- SQL Server基础知识之:设计和实现视图
- IncrediBuild联合编译的使用
- TopLink