【问题标题】:What is the ideal & fastest way to communicate between kernel and user space?在内核和用户空间之间进行通信的理想和最快的方式是什么?
【发布时间】:2009-06-02 22:36:05
【问题描述】:

我知道信息交换可以通过内核和用户空间程序之间的以下接口进行

  • 系统调用

  • ioctls

  • /proc & /sys

  • 网联

我想知道

  • 如果我错过了任何其他界面?

  • 其中哪一种是交换大量数据的最快方式? (如果有任何文件/邮件/解释支持这种说法,我可以参考)

  • 推荐哪一种沟通方式? (我认为它的网络链接,但仍然很想听听意见)

【问题讨论】:

  • 如果你准确地说出你打算做什么,你会得到更合适的答案。
  • 试图将网络数据包从内核传输到用户空间程序,反之亦然。
  • 我认为netlink应该是最好的数据包交换方式
  • 是的,除了它是一个有损连接的事实。一旦队列满了,数据就会被丢弃,没有任何通知。

标签: linux linux-kernel


【解决方案1】:

交换大量数据的最快方法是内存映射。 mmap 调用可用于设备文件,然后相应的内核驱动程序可以决定将内核内存映射到用户地址空间。一个很好的例子是 Video For Linux 驱动程序,我想帧缓冲区驱动程序的工作方式相同。要很好地解释 V4L2 驱动程序的工作原理,您有:

对于大量数据,您无法击败内存映射,因为不涉及类似 memcopy 的操作,物理底层内存在内核和用户空间之间有效共享。当然,就像在所有共享内存机制中一样,您必须提供一些同步,以便内核和用户空间不会认为它们同时拥有所有权。

【讨论】:

    【解决方案2】:

    共享内存在内核和使用空间之间是可行的。

    http://kerneltrap.org/node/14326

    用于说明/示例。

    您也可以使用非常快的命名管道

    所有这一切实际上都取决于您要共享的数据、是否同时访问以及数据的结构。对于简单的数据,调用可能就足够了。

    Linux kernel /proc FIFO/pipe

    或许也有帮助

    祝你好运

    【讨论】:

      【解决方案3】:

      你也可以考虑使用relay(以前的relayfs):

      “基本上,relayfs 只是一堆 per-cpu 内核缓冲区,可以从内核代码有效地写入这些缓冲区。这些缓冲区表示为可以映射并直接从用户空间中读取的文件。这样做的目的setup 是提供最简单的机制,允许潜在的大量数据记录到内核中并“中继”到用户空间。”

      http://relayfs.sourceforge.net/

      【讨论】:

      • 谢谢。但它似乎是单向交通。我也想转回内核。
      【解决方案4】:

      您显然可以使用 copy_from_user 等进行共享内存,您可以轻松设置字符设备驱动程序,基本上您所要做的就是创建一个 file_operation 结构,但这并不是最快的方法。 我没有基准,但现代系统上的系统调用应该是最快的。我的理由是它是最优化的。过去,从用户到内核必须创建一个中断,然后它会转到中断表(一个数组),然后找到中断句柄(0x80),然后进入内核模式。这真的很慢,然后是 .sysenter 指令,这基本上使这个过程非常快。不详述,.sysenter 立即从寄存器 CS:EIP 中读取,并且更改非常快。 相反,共享内存需要写入和读取内存,这比从寄存器读取要昂贵得多。

      【讨论】:

      • 当然你的意思是“几个数量级”而不是“无限”[/nitpick]
      • 无论您是int 还是sysenter,系统调用仍然需要上下文切换和保存/恢复寄存器。 shmem 写入进入 CPU 缓存,而不是直接写入内存,因此速度很快,除非缓存未命中。
      【解决方案5】:

      这是所有可能接口的可能编译,尽管在某些方面它们相互重叠(例如,套接字和系统调用都有效地使用系统调用):

      Procfs
      Sysfs
      Configfs
      Debugfs
      Sysctl
      devfs (eg, Character Devices) 
      TCP/UDP Sockets
      Netlink Sockets 
      Ioctl
      Kernel System Calls
      Signals
      Mmap
      

      【讨论】:

        【解决方案6】:

        至于共享内存,我发现即使使用 NUMA,运行在两个不同内核上的两个线程通过共享内存进行通信仍然需要从 L3 缓存写入/读取,如果幸运的话(在一个套接字中)是 比 syscall 慢大约 2X,如果(不在一个套接字上),大约是 5X-UP 比系统调用慢,我认为系统调用的硬件机制有所帮助。

        【讨论】:

          猜你喜欢
          • 2011-05-25
          • 1970-01-01
          • 2012-07-15
          • 1970-01-01
          • 2011-03-02
          • 1970-01-01
          • 1970-01-01
          • 2014-11-06
          • 2013-01-02
          相关资源
          最近更新 更多