Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用O_SYNC时,mmap非常慢_C_Linux Device Driver_Embedded Linux_Mmap_Ethernet - Fatal编程技术网

使用O_SYNC时,mmap非常慢

使用O_SYNC时,mmap非常慢,c,linux-device-driver,embedded-linux,mmap,ethernet,C,Linux Device Driver,Embedded Linux,Mmap,Ethernet,我们的项目简介:我们在项目中使用CycloneV,FPGA将使用AXI总线将数据写入DDR,我们的应用程序需要使用以太网将数据发送出去。我们使用iperf测试我们的以太网吞吐量,它可以达到大约700Mbps的速度。当我们测试应用程序吞吐量时,得到的结果只有400Mbps。我们不使用/dev/mem编写一个简单的服务器代码,然后使用dd命令用随机数据填充内存,应用程序读取要发送的文件。我们注意到吞吐量实际上接近iperf基准。我们发现,当我们在open/dev/mem期间删除O_SYNC时,可以实

我们的项目简介:我们在项目中使用CycloneV,FPGA将使用AXI总线将数据写入DDR,我们的应用程序需要使用以太网将数据发送出去。我们使用iperf测试我们的以太网吞吐量,它可以达到大约700Mbps的速度。当我们测试应用程序吞吐量时,得到的结果只有400Mbps。我们不使用
/dev/mem
编写一个简单的服务器代码,然后使用
dd
命令用随机数据填充内存,应用程序读取要发送的文件。我们注意到吞吐量实际上接近iperf基准。我们发现,当我们在open
/dev/mem
期间删除O_SYNC时,可以实现接近iperf的吞吐量。但现在的问题是,如果不使用O_SYNC,我们会得到间歇性错误数据

我们使用
dma\u alloc\u coherent
分配连续内存:

p_ximageConfig->fpgamem_virt = dma_alloc_coherent(NULL, Dma_Size, &(p_ximageConfig->fpgamem_phys), GFP_KERNEL);
我们使用IOCTL将phys内存传递给userspace到mmap:

uint32 DMAPHYSADDR = getDmaPhysAddr();
pImagePool = ((volatile unsigned char*)mmap( 0,MAPPED_SIZE_BUFFER, PROT_READ|PROT_WRITE, MAP_SHARED, _fdFpga, DMAPHYSADDR));
我们尝试了以下方法:

  • 在驱动程序中编写自己的mmap:如果不同步,我们仍然会间歇性地获得错误数据。我们尝试的同步方法是pgprot\u noncachedpgprot\u dmacoherent,但它只能达到300Mbps

  • 我们尝试使用dma_mmap_相干:我们得到的结果约为500Mbps


  • 是否有任何方法可以帮助我们实现接近iperf性能的性能?

    我不知道为什么
    iperf
    如此之快,但是
    mmap
    如何使用设备内存

    让我们看看,它是由用户的
    mmap
    调用调用的。根据,如果指定了
    O_SYNC
    ,则此函数将内存映射为非缓存,并将其映射为(可能)写回否则。这样做
    vma->vm_page_prot=u pgprot_modify(vma->vm_page_prot,L_PTE_MT_MASK,L_PTE_MT_WRITEBACK)可能会使它更快

    所以这里我们启用了一个内存区域的缓存。那么如何将内容与FPGA同步呢

    一种方法是通过软件进行同步。有对应于和相应的和呼叫。这些函数有三个参数:用户地址
    addr
    、大小
    size
    和DMA方向
    dir

    当我们调用
    dmac\u映射区域(addr,size,DMA\u到设备)
    时,CPU缓存的内容被写入内存。因此,当CPU已经完成对内存的写入,并且设备将从该位置读取时,请执行此操作

    当我们调用
    dmac\u unmap\u区域(addr,size,DMA\u FROM\u DEVICE)
    时,CPU缓存的内容被标记为“无效”,当我们从该位置读取时,来自设备的新内容被读取到CPU缓存。因此,当设备完成对内存的写入并且CPU将从该位置读取时,请执行此操作

    另一种方法是使用专用硬件。据介绍,Cyclone V具有加速器一致性端口(ACP),使FPGA能够读取ARM的缓存内容。我认为这可能比软件快,但因为我不知道如何使用ACP,请尝试谷歌搜索