【问题标题】:Linux sockets: Zero-copy local, TCP/IP remoteLinux 套接字:本地零拷贝、远程 TCP/IP
【发布时间】:2011-12-28 21:15:01
【问题描述】:

网络是我在操作系统中最糟糕的领域,所以请原谅我问了一个可能不完整的问题。我已经阅读了几个小时,但它有点在我脑海中游泳。 (对我来说,我觉得芯片设计比搞清楚网络协议要容易。)

我有一些通过套接字相互通信的网络服务。具体来说,套接字是使用fd = socket(PF_INET, SOCK_STREAM, 0); 创建的,它会自动获取 TCP/IP。我需要这个作为基本情况,因为这些服务可能在不同的机器上运行。

但是对于一个项目,我们正试图将它们全部压缩到基于 Atom Z530P 的动力不足的嵌入式“设备”中,因此在我看来,内存复制开销是我们可以优化的东西。我一直在这里阅读:data-link-access-and-zero-copyLinux_packet_mmappacket_mmap

对于这种情况,可以像这样创建套接字:fd = socket(PF_PACKET, PF_RAW, 0);。还有很多其他的事情要做,比如分配环形缓冲区、映射它们、将它们与套接字关联等等。看起来你被限制使用sendtorecvfrom 来传输数据。据我了解,由于套接字是本地的,因此您不需要可靠的“流”类型套接字,因此原始套接字是合适的接口,我 猜测 使用了环形缓冲区在页面粒度上,每个数据包(或数据报)从页面边界开始。

在我花费大量时间尝试进一步调查之前,我希望一些乐于助人的人可以帮助我解决一些问题:

  • 我应该期望从零拷贝套接字获得多少性能优势?我想我最后一次检查时,我们将最大值从一个进程移动到另一个进程,最后移动到磁盘。在最基本的场景中,数据从捕获进程移动到一对多进程(其他人可以在流上监听),再到写入磁盘的归档进程。那是两跳,不包括磁盘和内部的东西。
  • Linux 是否会自动执行这些操作,针对同一台机器上运行的进程进行优化?
  • 无论如何,我都会在 TCP 端口中设置监听套接字。我可以使用它们在进程之间建立连接但仍然可以使用零拷贝吗?换句话说,我可以将 AF_INET 与 PF_PACKET 一起使用吗?
  • 带有 SOCK_RAW 的 PF_PACKET 是零拷贝套接字的唯一有效配置吗?
  • 是否有任何好的示例代码可以使用 TCP/IP 的零拷贝作为后备?
  • 检测两个进程是否在同一台计算机上的最简单或最佳方法是什么?他们知道彼此的 IP 地址,所以我可以比较并为每个人使用不同的代码路径。有没有更简单的方法来做到这一点?
  • 我可以在基于数据包的套接字上使用 write() 和 read(),还是只对流有效? (重写如何建立连接会比重写所有套接字代码更简单。)
  • 我是否使事情过于复杂和/或优化了错误的事情? OProfiler 告诉我,大部分 CPU 时间都花在了两个地方:(1) zlib 和 (2) 内核,因为我使用的是不提供 vmlinux 的 CentOS 6.2,所以我无法对其进行分析。我假设内核时间是空闲时间和数据复制的组合,仅此而已。

提前感谢您的帮助!

【问题讨论】:

    标签: linux sockets zero-copy


    【解决方案1】:

    我是否让事情过于复杂和/或优化了错误的事情?

    可能。使用PF_PACKET 套接字仅适用于专门的东西。你可能想看看

    检测这两个进程的最简单或最佳方法是什么 在同一台机器上?

    不要“忘记”这些信息。

    Linux 是否会自动执行这些操作,针对进程进行优化 在同一台机器上运行?

    不,你必须自己做。

    【讨论】:

      【解决方案2】:

      我认为 TCP/IP 和原始数据包之间的选择比零拷贝问题重要得多。如果需要可靠的基于流的通信,则需要 TCP/IP(即 AF_INET+PF_STREAM)。尝试在不可靠的数据包上实现可靠的流是非常复杂的,并且已经为您完成了。

      使用 TCP/IP 零拷贝和文件的最佳方式是,正如@cnicutar 所说,sendfile(2) 和 splice(2)。我认为有一种方法可以在没有这些的情况下享受零拷贝(如果你想将数据读入内存,而不是直接读入文件),但我不知道该怎么做。

      另外,Centos 是开源的,所以你可以通过下载源代码并编译得到一个 vmlinux 文件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-25
        • 2016-04-18
        • 2017-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-01
        • 2017-07-06
        相关资源
        最近更新 更多