Chinaunix首页 | 论坛 | 博客
  • 博客访问: 485731
  • 博文数量: 41
  • 博客积分: 4007
  • 博客等级: 中校
  • 技术积分: 725
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-30 15:43
文章分类

全部博文(41)

文章存档

2011年(13)

2010年(14)

2009年(2)

2008年(12)

分类: C/C++

2011-01-17 16:00:22

发信人: fec (lovemel), 信区: LinuxDev
标  题: Re: 如果已知一段内存不用了,是否可以手动放到对换区中
发信站: 水木社区 (Tue Oct 19 15:50:39 2010), 站内

果然灵验,只换了一下内存分配的方式。
缺页导致的效率之差一下就明显开来,而且没有errno了。
用top看,按了y键后,内存一下由512M减到256M,看来kernel是接受了advise,不错啊,不错。

多谢v侠,k侠指点。

代码土点,大家莫笑。

#include
#include
#include
#include
#include
#include
#include
#include
#define GET_REAL_CPU_TICKS(Var) __asm__ __volatile__ ("rdtsc" : "=A" (Var))
#define get_cpu_ticks(Var) GET_REAL_CPU_TICKS(Var)

#define LINESIZE 64
#define DATASIZE 1024*1024*64*4
char clear[DATASIZE];

void clear_cache()
{
        register char *p = (char*)clear;
        for(int i = 0;i<4*1024*1024;++i)
        {
                (*p)++;
                p+=LINESIZE;
        }
}

void visit_all(void* data)
{
        char *p = (char*)data;
        for(int i = 0;i<4*1024*1024;++i)
        {
                (*p)++;
                p+=LINESIZE;
        }
}

void adv(void* data)
{
        int ret = madvise(data,DATASIZE,MADV_DONTNEED);
        printf("%d\n",ret);
}

void loc(void* data)
{
        int ret = mlock(data,DATASIZE);
        printf("%d\n",ret);
}

int main(int argc, char **argv)
{
        void* data1 = NULL;
        void* data2 = NULL;
        data1 = mmap(0,DATASIZE,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,0,0);
        data2 = mmap(0,DATASIZE,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,0,0);
        //printf("%d\n",errno);
        visit_all(data1);
        visit_all(data2);
        while(getchar()!='y')
        {
                printf("input command y\n");
        }
        adv(data1);
        while(getchar()!='c')
        {
                printf("input command c\n");
        }
        loc(data2);//if change to adv(data1),tow cost same
        /////////////////dat2 in memory while data1 out of memory//////////////
        clear_cache();  //make data2 out of cache
        register int start, end;
        get_cpu_ticks(start);
        visit_all(data2);
        get_cpu_ticks(end);
        printf("in memory time  %d\n",end-start);

        clear_cache(); //make data2 out of cache
        get_cpu_ticks(start);
        visit_all(data1);
        get_cpu_ticks(end);
        printf("out memory time %d\n",end-start);

        munmap(data1,DATASIZE);
        munmap(data2,DATASIZE);
}

上面是从水木上转过来的
下面的代码是经我测试过的:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define DATASIZE 1024*1024*100

int main(int argc, char **argv)
{
void* data1 = NULL;
void* data2 = NULL;
#if 0
int fd = open("mmap", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
if (fd < 0)
perror("open");
if (lseek(fd, DATASIZE+DATASIZE, SEEK_SET) < 0)
perror("lseek");
char t = 0;
write(fd, &t, 1);
#endif
data1 = mmap(0,DATASIZE,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,0,0);
if (data1 == MAP_FAILED)
perror("mmap");
data2 = mmap(0,DATASIZE,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,0,0);
//data2 = mmap(0,DATASIZE,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,DATASIZE);
if (data2 == MAP_FAILED)
perror("mmap");
int i = 0;
for (i = 0; i < DATASIZE; i++)
((unsigned char *)data1)[i] = 1;
int ret = 0;
for (i = 0; i < DATASIZE; i++)
ret += ((unsigned char *)data1)[i];
printf("before madvise ret=%d\n", ret);
memset(data2, 0, DATASIZE);
printf("init ok!\n");
    while(getchar()!='y')
    {
        printf("input command y\n");
    }
//printf("msync data1\n");
//if (msync(data1, DATASIZE, MS_SYNC) < 0)
//perror("msync");
//printf("msync data1 done\n");
ret = madvise(data1,DATASIZE,MADV_DONTNEED);
printf("madvise ret: %d\n",ret);
printf("free phy memory\n");
while(getchar()!='c')
{
printf("input command c\n");
}
ret = 0;
for (i = 0; i < DATASIZE; i++)
ret += ((unsigned char *)data1)[i];
printf("ret:%d\n", ret);

while(getchar()!='q')
{
printf("input command q\n");
}
munmap(data1,DATASIZE);
munmap(data2,DATASIZE);
//close(fd);
return 0;
}
阅读(838) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~