Chinaunix首页 | 论坛 | 博客
  • 博客访问: 353526
  • 博文数量: 90
  • 博客积分: 2017
  • 博客等级: 大尉
  • 技术积分: 615
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-19 08:10
文章分类

全部博文(90)

文章存档

2012年(4)

2011年(74)

2010年(11)

2009年(1)

分类: C/C++

2011-05-30 20:11:34

linux下零拷贝技术的实现(zero-copy)
零拷贝(zero-copy)是只使用内存映射技术实现在内核与应用层之间的数据传递,由于内核与应用层使用的是同一块内存,取消了内核向用户空间的拷贝过程,会很大程度上提高系统效率。

  实际应用,有一数据采集设备A,产生大量数据流,应用层读取通过该设备驱动获得数据,处理后,在通过网卡分发出去。在实际应用的过程中,数据要由A驱动copy到应用层,再由应用层处理后再次走网卡驱动,cpu除了要进行大量的应用处理(计算)还要copy,效率很低,接收端会出现数据卡的现象。采用zero-copy技术就可以解决这个问题。

具体实现:
内核端

#define SH_MEM_SIZE (1024*1024*2)

int order;
unsigned long shmem_virt_addr;
unsigned long shmem_phy_addr;

order = get_order(SH_MEM_SIZE);
shmem_virt_addr = __get_free_pages(GFP_KERNEL, order);
SetPageReserved(virt_to_page(shmem_virt_addr));
shmem_phy_addr=virt_to_phys(shmem_virt_addr);
printk("[shmem_phy_addr= %x]\n",shmem_phy_addr);
copy_to_user(arg,&shmem_phy_addr,sizeof(long));

//shmem_virt_addr 内核使用,可以直接写入数据
//shmem_phy_addr 需要提供给应用层


应用
shmem_phy_addr = get_phy_addr(); //获得内核传过来的物理地址
printf("[shmem_phy_addr= %x]\n",shmem_phy_addr);
fd=open("/dev/mem",O_RDWR);
if(fd == -1){
    perror("open mem");
}
buf=mmap(0,SH_MEM_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,fd,shmem_phy_addr);
if(buf == MAP_FAILED){
    perror("mmbuf error!\n");
}
//buf存放共享后的内存指针,应用层可以直接读取buf中的内容

阅读(4285) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~