C mmap&x27;内存访问非常慢
我使用v4l2通过流式io从摄像机获取视频帧,需要对帧进行一些计算 但是,访问帧内存的速度比分配内存慢10倍 记忆混乱 我猜mmap帧内存不可由cpu缓存。 这是测试代码C mmap&x27;内存访问非常慢,c,mmap,v4l2,C,Mmap,V4l2,我使用v4l2通过流式io从摄像机获取视频帧,需要对帧进行一些计算 但是,访问帧内存的速度比分配内存慢10倍 记忆混乱 我猜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(_fdC
//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;
}
缓存摄影机帧缓冲区没有任何意义。想象一下如果你这样做会发生什么。摄影机在看到的场景发生变化时会继续更新帧缓冲区,但缓存永远不会更新。您必须每X毫秒使缓存失效一次,以保持帧更新。那太糟糕了。Imstead、memcpy或DMA删除帧缓冲区的副本,并对副本执行所有计算。