【问题标题】:receive data from multicast socket in linux with lowest latency从 linux 中以最低延迟接收多播套接字的数据
【发布时间】:2014-09-19 14:58:48
【问题描述】:

在 HFT 交易应用程序中,我需要从 udp 多播套接字接收数据。唯一的要求是延迟——这非常重要,以至于我可以“使用”一个 CPU 内核。旋转什么的都可以。这是我目前在 Windows 中所拥有的:

void Receiver::ThreadMethod() {
    //UINT32 seq;
    sockaddr_in Sender;
    int SenderAddrSize = sizeof(Sender);

    while (stayConnected) {
        int res=recvfrom(socketId,buf,sizeof(char) * RECEIVE_BUFFER_SIZE,0, (SOCKADDR *)& Sender, &SenderAddrSize);
        if (res == SOCKET_ERROR) {
            printf("recvfrom failed, WSAGetLastError: %d\n", WSAGetLastError());
            continue;
        }
        //seq = *(UINT32*)buf;
        //printf("%12s:seq=%6d:len=%4d\n", inet_ntoa(Sender.sin_addr), seq, res);
        unsigned char* buf2 = reinterpret_cast<unsigned char*>(buf);
        feed->ProcessMessage(res, buf2);
    }
}

recvfrom 块,所以它可能会很慢(或者我错了?)。我应该为 Linux 重写它并实现最佳延迟。我需要为每个线程处理一个套接字,所以我认为我不应该使用epoll,因为它更多地设计用于处理多个套接字。我应该使用什么?

更新我发现了类似的问题Low-latency read of UDP port

【问题讨论】:

  • 不清楚为什么您认为阻塞的 recvfrom() 调用会很慢。确实,如果没有收到数据包,它不会在很长一段时间内返回,但是如果/当收到数据包时,它应该立即返回。您担心的是上下文切换开销吗?
  • 顺便说一句,如果你想保证低延迟,你可以看看 Xenomai 的 Linux 实时扩展,因为这就是他们提供的。
  • @JeremyFriesner 阻止总是很昂贵,这就是人们“旋转”的原因
  • “阻塞总是很昂贵”
  • @JeremyFriesner 我认为这是因为当你阻止时,你会花时间“唤醒”,当你不阻止时,你会节省这段时间)

标签: c++ linux sockets hft


【解决方案1】:

在 UNIX 中,您应该使用 fcntl 将您的套接字设置为非阻塞:

fcntl(socket, F_SETFL, O_NONBLOCK);

此外,如果您的客户端需要处理多个套接字(例如,聚合多个提要),您应该使用select 调用一次处理多个文件描述符,并查看哪个套接字有可用数据(如果有)(这将,除其他外,避免循环遍历所有套接字)

至于延迟,其他因素如网卡类型和配置、内核设置(可能有一个绕过内核的网卡)会对延迟产生相当大的影响(待测)。

【讨论】:

  • 据我所知,在低延迟情况下,最好使用“一个线程 - 一个套接字”。另请注意,我在两个套接字上都收到相同的数据。使用两个线程可以并行接收两个数据包,这应该会稍微改善延迟。
  • NIC 和其他一切都配置得非常出色,并且在这个星球上速度最快,只有尚未编写的软件。
  • @javapowered 不,它不是“一个线程一个套接字”,大多数处理程序在一两个 CPU 上旋转选择,但这完全取决于您可用的硬件。 (无论如何,多个线程将获得对 NIC 的并发访问 + 运行它们的上下文切换成本)。跳这个有帮助。
猜你喜欢
  • 2013-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多