【问题标题】:Poor multicast performance sending using boost::asio on Windows在 Windows 上使用 boost::asio 发送多播性能不佳
【发布时间】:2015-11-16 18:43:13
【问题描述】:

我有一个非常简单的 boost::asio 套接字发送多播消息的包装器:

// header
class MulticastSender
{
public:

    /// Constructor
    /// @param ip - The multicast address to broadcast on
    /// @param port - The multicast port to broadcast on
    MulticastSender(const String& ip, const UInt16 port);

    /// Sends a multicast message
    /// @param msg - The message to send
    /// @param size - The size of the message (in bytes)
    /// @return number of bytes sent
    size_t send(const void* msg, const size_t size);

private:

    boost::asio::io_service m_service;
    boost::asio::ip::udp::endpoint m_endpoint;
    boost::asio::ip::udp::socket m_socket;

};

// implementation
inline MulticastSender::MulticastSender(const String& ip, const UInt16 port) :
    m_endpoint(boost::asio::ip::address_v4::from_string(ip), port),
    m_socket(m_service, m_endpoint.protocol())
{
    m_socket.set_option(boost::asio::socket_base::send_buffer_size(8 * 1024 * 1024));
    m_socket.set_option(boost::asio::socket_base::broadcast(true));
    m_socket.set_option(boost::asio::socket_base::reuse_address(true));
}

inline size_t MulticastSender::send(const void* msg, const size_t size)
{
    try
    {
        return m_socket.send_to(boost::asio::buffer(msg, size), m_endpoint);
    }
    catch (const std::exception& e)
    {
        setError(e.what());
    }
    return 0;
}

// read and send a message
MulticastSender sender(ip, port);
while(readFile(&msg)) sender.send(&msg, sizeof(msg));

在 Windows 7 上使用 Visual Studio 2013 编译时,在 Ubuntu 14.04 ~100 MB/s 上的吞吐量约为 11 MB/s。我添加了计时器,并且能够验证 send(...) 方法是罪魁祸首。

我尝试过启用和不启用防病毒软件,并尝试禁用其他一些服务,但没有成功。由于计算机上的权限(例如防火墙),我无法禁用一些。

我假设在 Windows 上运行的服务会产生干扰,或者我的实现缺少一些影响 Windows 而不是 Linux 上的应用程序的东西。

任何关于可能导致这种情况的想法将不胜感激

【问题讨论】:

  • 我假设您编译时使用了适当的优化?
  • 是的,没有调试信息,/O2 /Ot
  • windows上的网卡设置怎么样?我不确定,但它可能没有为此用例优化设置
  • 它们将是默认值,不确定它们应该设置为最佳多播发送
  • 您是否尝试过不使用 boost 进行此操作?通过 Win32 API 直接调用?我假设您会看到相同的结果,但也许它是 boost 中的错误实现?

标签: c++ boost multicast


【解决方案1】:

windows 和 ubuntu 是在同一台机器上运行的吗?

如果没有,您的 windows 机器似乎受限于 100Mbit 以太网,而 ubuntu 机器似乎使用 1Gbit 以太网。

(如果这不是问题的原因,我很抱歉发布 anwser 而不是评论。但我不能这样做,你的代码很简单,数据速率很明显 [11*8MB /s ~ 100Mbit/s 和 100MB/s ~ 800Mbit/s]。我只需要做出那个提示...)

【讨论】:

  • 它们是不同的机器,但都有千兆网卡。但是你确实提出了一个关于费率的有趣观点。我现在很好奇是否有什么东西导致 Windows 机器只允许 UDP/Multicast 以 100 Mbit 的速度运行
  • 两台机器都使用千兆以太网电缆吗?还有一个非常重要的方面:您是否将网络节流索引设置为 0xffffffff!?这绝对会导致您的 Windows 机器上的 UDP 包丢失。
  • 是的,电缆就足够了。我的 NAS 速率超过 70MB/s。我将网络节流索引更改为 0xffffffff,没有任何变化。
【解决方案2】:

如果您的数据传输量很大,比如超过 10 MB 的消息,我建议您使用 TCP 而不是 UPD/多播。 TCP 是一种可靠的协议。

我读到一个案例,其中一个 300 字节数据包流通过以太网(1500 字节 MTU)发送,TCP 比 UDP 快 50%。因为 TCP 会尝试缓冲数据并填充整个网段,从而更有效地利用可用带宽,但 UDP 会立即将数据包放在网络上,从而使网络因大量小数据包而拥塞。在 Windows 中,我建议您使用 TCP over UDP/Multicast。

【讨论】:

  • 无法使用 TCP。多个接收器正在侦听数据。我不需要修改源代码,因为它在 Linux 上完美运行,我唯一的问题是在 Windows 上它更慢,太慢了。
  • 另外值得一提的是,正在发送的数据以类似于 TCP 的方式进行缓冲,因此有效负载大小接近网络的 MTU。目前,我认为正在发送的数据包每个是 1372 字节
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-26
  • 2012-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多