首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >mmap比ioremap慢

mmap比ioremap慢
EN

Stack Overflow用户
提问于 2012-06-07 09:18:30
回答 2查看 7K关注 0票数 13

我正在开发一个运行Linux2.6.37的ARM设备。我正在尽可能快地切换一个IO引脚。我制作了一个小内核模块和一个用户空间应用程序。我试了两件事:

ioremap.

  • mmap()使用
  1. 直接从内核空间操作GPIO控件寄存器,无需缓存并在用户空间使用。

这两种方法都有效,但第二种方法比第一种方法慢3倍(在示波器上观察到)。我想我禁用了所有的缓存机制。

当然,我想从这两个世界中得到最好的结果:以内核空间的速度从用户空间中获得灵活性和易于开发。

有人知道为什么mmap()会比ioremap()慢吗?

这是我的密码:

内核模块代码

代码语言:javascript
复制
static int ti81xx_usmap_mmap(struct file* pFile, struct vm_area_struct* pVma)
{
  pVma->vm_flags |= VM_RESERVED;
  pVma->vm_page_prot = pgprot_noncached(pVma->vm_page_prot);

  if (io_remap_pfn_range(pVma, pVma->vm_start, pVma->vm_pgoff,
                          pVma->vm_end - pVma->vm_start, pVma->vm_page_prot))
     return -EAGAIN;

  pVma->vm_ops = &ti81xx_usmap_vm_ops;
  return 0;
}

static void ti81xx_usmap_test_gpio(void)
{
  u32* pGpIoRegisters = ioremap_nocache(TI81XX_GPIO0_BASE, 0x400);
  const u32 pin = 1 << 24;
  int i;

  /* I should use IO read/write functions instead of pointer deferencing, 
   * but portability isn't the issue here */

  pGpIoRegisters[OMAP4_GPIO_OE >> 2] &= ~pin;    /* Set pin as output*/

  for (i = 0; i < 200000000; ++i)
  {
     pGpIoRegisters[OMAP4_GPIO_SETDATAOUT >> 2] = pin;
     pGpIoRegisters[OMAP4_GPIO_CLEARDATAOUT >> 2] = pin;
  }

  pGpIoRegisters[OMAP4_GPIO_OE >> 2] |= pin;    /* Set pin as input*/

  iounmap(pGpIoRegisters);
}

用户空间应用程序代码

代码语言:javascript
复制
int main(int argc, char** argv)
{
   int file, i;
   ulong* pGpIoRegisters = NULL;
   ulong pin = 1 << 24;

   file = open("/dev/ti81xx-usmap", O_RDWR | O_SYNC);

   if (file < 0)
   {
      printf("open failed (%d)\n", errno);
      return 1;
   }


   printf("Toggle from kernel space...");
   fflush(stdout);

   ioctl(file, TI81XX_USMAP_IOCTL_TEST_GPIO);

   printf(" done\n");    

   pGpIoRegisters = mmap(NULL, 0x400, PROT_READ | PROT_WRITE, MAP_SHARED, file, TI81XX_GPIO0_BASE);
   printf("Toggle from user space...");
   fflush(stdout);

   pGpIoRegisters[OMAP4_GPIO_OE >> 2] &= ~pin;

   for (i = 0; i < 30000000; ++i)
   {
      pGpIoRegisters[OMAP4_GPIO_SETDATAOUT >> 2] = pin;
      pGpIoRegisters[OMAP4_GPIO_CLEARDATAOUT >> 2] = pin;
   }

   pGpIoRegisters[OMAP4_GPIO_OE >> 2] |= pin;

   printf(" done\n");
   fflush(stdout);
   munmap(pGpIoRegisters, 0x400);    

   close(file);    
   return 0;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-28 21:34:32

这是因为ioremap_nocache()仍然在VM映射中启用CPU写缓冲区,而pgprot_noncached()则禁用可缓存性和缓存性。

苹果与苹果的比较是使用ioremap_strongly_ordered()代替。

票数 8
EN

Stack Overflow用户

发布于 2012-06-08 17:34:24

我的猜测是,由于mmap必须检查以确保您被允许写入内存,所以它将比内核版本慢(我认为/假设内核版本不会进行这种检查--使用内核模块负责测试,直到非常确定您没有破坏程序)。

尝试从内核空间使用do_mmap (我相信这就是其中的一种),看看比较如何。如果速度要快得多,那我是对的。如果不是,那是另外一回事。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10928978

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档