mmap的内存访问非常慢

时间:2014-10-18 13:45:00

标签: c mmap v4l2

我使用v4l2使用流式传输来从相机获取视频帧,需要对帧进行一些计算。

然而,访问帧存储器比分配慢10倍 一个malloc的记忆。

我猜mmap的帧内存不能被cpu缓存。

这是测试代码。

//mmap video buffers
struct v4l2_buffer buf;
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
if (-1 == xioctl(_fdCamera, VIDIOC_QUERYBUF, &buf)) {
    ERROR("VIDIOC_QUERYBUF");
    goto error_querybuf;
}
_buffers[i].start = mmap(NULL, buf.length,
PROT_READ | PROT_WRITE,
MAP_SHARED, _fdCamera, buf.m.offset);


//use mmap'ed buffer to do some calculation
u16* frame=_buffers[0].start;

u64 sum=0;
u16* p=frame;
time[0]=GetMicrosecond64();
while(p!=frame+PIXELS){
    sum+=*p;
    p++;
}
time[1]=GetMicrosecond64();
printf("mmap:sum %lld,time %lld\n",sum, time[1] - time[0]);

//use a copy of data to do some calculation
u16* frame_copy=(u16*)malloc(PIXELS*2);
memcpy(frame_copy,frame,PIXELS*2);
sum=0;
p=frame_copy;
time[0]=GetMicrosecond64();
while(p!=frame_copy+PIXELS){
    sum+=*p;
    p++;
}
time[1]=GetMicrosecond64();
printf("malloc:sum %lld,time %lld\n",sum, time[1] - time[0]);

更新

我在linux-2.6.35中使用s5pv210.fimc_dev.c表示mmaped未缓存。

如何使帧缓冲内存支持DMA和缓存?

static inline int fimc_mmap_cap(struct file *filp, struct vm_area_struct *vma)
{
    struct fimc_prv_data *prv_data =
                (struct fimc_prv_data *)filp->private_data;
    struct fimc_control *ctrl = prv_data->ctrl;
    u32 size = vma->vm_end - vma->vm_start;
    u32 pfn, idx = vma->vm_pgoff;

    vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
    vma->vm_flags |= VM_RESERVED;

    /*
     * page frame number of the address for a source frame
     * to be stored at.
     */
    pfn = __phys_to_pfn(ctrl->cap->bufs[idx].base[0]);

    if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) {
        fimc_err("%s: writable mapping must be shared\n", __func__);
        return -EINVAL;
    }

    if (remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot)) {
        fimc_err("%s: mmap fail\n", __func__);
        return -EINVAL;
    }

    return 0;
}

0 个答案:

没有答案