DongHao: 02 2011存档
inux kernel里是不区分进程/线程的,都用的是struct task_struct结构。如果一个进程启动,然后创建n个线程,那么对内核来说,就是多了n+1个struct task_struct结构而已,且这后n+1个task_struct里的成员指针group_leader指向那个创建它们的进程。这个创建其它人的进程当然就是这个thread group的leader。
但是在2.6.18版kernel里,一个thread group里的task_struct共享统一各rlim实例,也就是说,你在任意一个线程里setrlimit,所有该thread group里的线程,包括那个创建者进程,都会改变资源限制状态。
我是在redhat 4u和5u机器上分别跑同一套代码,发现这一不同的。
判断上百万个4k的buffer是否为全0,我最先想到的办法是:
zero_buffer = malloc(4096);
memset(zero_buffer, 0, 4096);
/* 循环百万次读取buffer */
if (!memcmp(zero_buffer, buffer)) {
/* 全0 */
}
做完以后跑了一下,速度凑合。由于好奇,看看shell工具cp的代码,它的解决办法是:
/* 循环百万次读取buffer */
long *wp = buffer;
while (*wp++ ==0 && wp<buffer + 4096)
continue;
if (wp >= buffer + 4096) {
/* 全0 */
}
cp的代码真称得上千锤百炼,这比我的方法要快,因为我的办法需要CPU访问两块内存(buffer和zero_buffer),而cp只问一块内存,CPU的cache会高效得多。
判断一块4k buffer当然看不出快慢,我们循环上百万次,立刻就能看出差别:cp的算法比我的快了3倍。
=== 2012.04.19 ===
首先感谢 bernie 的提问,我自己写了完整的代码来验证这个事儿:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define SIZE (1024*1024*1024)
void my_process(void *a, void *b)
{
if (memcmp(a, b, SIZE))
printf("wrong\n");
}
void cp_process(void *a)
{
long *wp = a;
while (*wp++ == 0 && wp < (long *)(a + SIZE))
continue;
}
int main(int argc ,char *argv[])
{
struct timeval start, end;
char * zero_buffer = (char*)malloc(SIZE);
memset(zero_buffer, 0, SIZE);
char * buffer = (char*)malloc(SIZE);
memset(buffer, 0, SIZE);
gettimeofday(&start, NULL);
my_process(buffer, zero_buffer);
gettimeofday(&end, NULL);
printf("my:%lu\n", (end.tv_sec * 1000000 + end.tv_usec) -
(start.tv_sec * 1000000 + start.tv_usec));
gettimeofday(&start, NULL);
cp_process(buffer);
gettimeofday(&end, NULL);
printf("my:%lu\n", (end.tv_sec * 1000000 + end.tv_usec) -
(start.tv_sec * 1000000 + start.tv_usec));
return 0;
}
绝对能编译,(大家注意,我只算内存比较的时间,什么malloc什么memset只是我的准备工作,不算在运行时间内的)我在一台开发机上跑了一下,结果是:
my:3428159
cp:611168
cp命令的算法显然比我的快。大家可以自己在机器上试试,如果结果不一样,咱们再研究研究 :)
另外,要注意那句
if (memcmp(a, b, SIZE))
printf("wrong\n");
不能直接写成
memcmp(a,b,SIZE);
因为只写“memcp“的话my_process函数会被编译器优化掉(因为函数没有返回值,也没有改全局变量,也就是说,没有任何”输出“),我猜 bernie 遇到的就是这个问题
关于存档
This page is a archive of recent entries written by DongHao in 02 % Y.
DongHao: 01 2011 is the previous archive.
DongHao: 03 2011 is the next archive.
Find recent content on the main index or look in the 存档 to find all content.
DongHao: 每月存档
- 02 2013 (2)
- 01 2013 (3)
- 12 2012 (6)
- 11 2012 (1)
- 10 2012 (4)
- 09 2012 (2)
- 08 2012 (4)
- 06 2012 (6)
- 05 2012 (2)
- 04 2012 (2)
- 02 2012 (3)
- 01 2012 (3)
- 12 2011 (2)
- 11 2011 (2)
- 10 2011 (6)
- 09 2011 (1)
- 08 2011 (3)
- 07 2011 (3)
- 06 2011 (3)
- 05 2011 (3)
- 04 2011 (3)
- 03 2011 (4)
- 02 2011 (2)
- 01 2011 (4)
- 12 2010 (5)
- 11 2010 (4)
- 10 2010 (5)
- 09 2010 (2)
- 08 2010 (7)
- 07 2010 (5)
- 06 2010 (5)
- 05 2010 (4)
- 04 2010 (5)
- 03 2010 (5)
- 02 2010 (7)
- 01 2010 (12)
- 12 2009 (11)
- 11 2009 (9)
- 10 2009 (10)
- 09 2009 (4)
- 08 2009 (8)
- 07 2009 (10)
- 06 2009 (4)
- 05 2009 (4)
- 04 2009 (6)
- 03 2009 (8)
- 02 2009 (5)
- 01 2009 (4)
- 12 2008 (5)
- 11 2008 (3)
- 10 2008 (8)
- 09 2008 (10)
- 08 2008 (7)
- 07 2008 (10)
- 06 2008 (6)
- 05 2008 (12)
- 04 2008 (12)
- 03 2008 (7)
- 02 2008 (5)
- 01 2008 (13)
- 12 2007 (9)
- 11 2007 (15)
- 10 2007 (29)
- 09 2007 (30)
- 08 2007 (24)
- 07 2007 (2)
- 06 2007 (7)
- 05 2007 (13)
- 04 2007 (8)
- 03 2007 (13)
- 02 2007 (8)
- 01 2007 (9)
- 12 2006 (7)
- 11 2006 (5)
- 10 2006 (6)
- 09 2006 (5)