C 以微秒级精度接收原始套接字数据包

C 以微秒级精度接收原始套接字数据包,c,linux,performance,sockets,networking,C,Linux,Performance,Sockets,Networking,我正在编写一个代码,它每1ms从服务器接收一次原始以太网数据包(没有TCP/UDP)。对于每收到一个数据包,我的应用程序必须回复14个原始数据包。如果服务器在发送计划为每1ms发送的数据包之前没有收到14个数据包,则服务器会发出警报,应用程序必须中断。服务器-客户端通信是一对一链接 服务器是一个硬件(FPGA),它以精确的1ms间隔生成数据包。客户端应用程序运行在带有10G SolarFlare NIC的Linux(RHEL/Centos 7)机器上 我的第一个版本的代码是这样的 while(1

我正在编写一个代码,它每1ms从服务器接收一次原始以太网数据包(没有TCP/UDP)。对于每收到一个数据包,我的应用程序必须回复14个原始数据包。如果服务器在发送计划为每1ms发送的数据包之前没有收到14个数据包,则服务器会发出警报,应用程序必须中断。服务器-客户端通信是一对一链接

服务器是一个硬件(FPGA),它以精确的1ms间隔生成数据包。客户端应用程序运行在带有10G SolarFlare NIC的Linux(RHEL/Centos 7)机器上

我的第一个版本的代码是这样的

while(1)
{
  while(1)
  {
     numbytes = recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL);
     if(numbytes > 0)
     {
        //Some more lines here, to read packet number
        break;
     }
  }
  for (i=0;i<14;i++)
  {
     if (sendto(sockfd,(void *)(sym) , sizeof(sym), 0, NULL, NULL) < 0)
            perror("Send failed\n");
  }
}
有时解码时间超过2000us,应用程序就会中断

在这种情况下,应用程序将在2秒到几分钟之间中断

我一直在尝试各种选择

  • 设置与特定隔离核心的关联
  • 使用
    SCHED\u FIFO将调度优先级设置为最大值
  • 增加套接字缓冲区大小
  • 将网络接口中断关联设置为处理应用程序的同一内核
  • 旋转
    recvfrom
    使用
    poll(),选择()
    调用
  • 所有这些选项都比初始版本的代码有了显著的改进。现在,应用程序将运行约1-2小时。但这仍然不够

    一些意见:

  • 每当我在应用程序运行时将ssh会话带到Linux机器上时,我都会收到大量的解码时间打印(这让我认为通过其他1G以太网接口进行的网络通信会对10G以太网接口造成干扰)
  • 应用程序在RHEL中的性能(运行时间约为2-3小时)优于Centos(运行时间约为30分钟-1.5小时)
  • 运行时间也因Linux机器的不同而不同,这些机器具有相同操作系统的不同硬件配置
  • 请建议是否有任何其他方法来提高应用程序的运行时间


    提前感谢。

    首先,您需要验证时间戳方法的准确性;计时。分辨率为纳秒,但精确度和精确度存在疑问。这并不是问题的答案,但在继续之前会告知时间戳的可靠性。请参阅了解为什么应用程序中应使用CLOCK_单调

    我怀疑大多数解码时间波动要么是由于每次解码的操作数量可变,要么是操作系统的上下文切换,要么是IRQ

    每次解码的操作我不能评论,因为代码已经在你的帖子中简化了。还可以分析和检查此问题

    每个进程的上下文切换可以很容易地检查和监视

    正如Ron所说,这些是对网络非常严格的定时要求。它必须是一个孤立的网络,且用途单一。当ssh'ing指示必须阻止所有其他流量时,您观察到的关于解码的时间变化。考虑到单独的NIC,这是令人不安的。因此,我怀疑IRQ是问题所在。请参阅/proc/interrupts

    要在较长的时间间隔(小时->天)内实现一致的解码时间,需要大大简化操作系统。删除不必要的进程和服务、硬件,或者构建自己的内核。所有这些都是为了减少上下文切换和中断。此时应考虑使用实时操作系统。这只会提高一致解码时间的概率,而不是保证


    我的工作是开发一个数据采集系统,它是FPGA、ADC、PC和以太网的组合。不可避免地,多用途PC的不一致性意味着某些功能必须转移到专用硬件。考虑开发PC应用程序的优点和缺点,将其移动到硬件。

    除了处理时间之外,您还需要了解,在现实世界中,网络将极大地改变分组传递时间。如果这些都在您的网络上(不在Internet上传输),如果您有可靠的QoS策略,并且您定义了此流量的优先级队列,那么您可以在一定程度上缓解这种情况。否则,我甚至不会尝试在网络上使用时间如此接近的东西。很高兴知道,你想要实现什么,当然,通过以太网发送如此精确的数据包是不可行的。我建议使用另一个FPGA来处理您的数据并与您的PC接口。@Vikram检查您的网络接口是否没有中断合并。为了减少CPU负载,通常会延迟网络接口上的中断处理,等待多个数据包到达,这样我们就可以在一个中断中处理多个数据包
    ethtool-c
    是查看这些值的工具,但是您需要找到关于这意味着什么的文档。也许会有帮助。你不能打败我。对于这种精确的要求,您的客户机也应该是NIC上的FPGA。这确实是唯一的解决方案。我使用
    CLOCK\u MONOTONIC
    来获取时间戳。计算出的时间与观察到的结果相符。我使用
    isolcpus
    kernel命令隔离了几个cpu内核。在使用
    ps-eF
    检查正在运行的进程时,我发现除了迁移、ksoftirqd、kworker之外,没有任何进程在这些孤立的核心上运行。我知道这些是不可避免的。
    Decode Time : 1234
    Decode Time : 762
    Decode Time : 1593
    Decode Time : 406
    Decode Time : 1703
    Decode Time : 257
    Decode Time : 1493
    Decode Time : 514
    and so on..