我们有一个Windows2003WindowsEnterprise64位服务器,运行一个自定义工作负载,性能问题很奇怪。下面缩小的版本有一个较小的驼峰,但在质量上是一样的。
我们已经将其简化为一个简单的、琐碎的应用程序,它只做了以下工作:
测试应用程序本身是Boost ASIO多播接收机示例的一个稍微修改过的版本,因此没有什么应该出错的地方。实际代码(!)低于…
在负载下运行此程序时,此进程的CPU通常会随着内核代码中发生的所有处理而增加:

(这里只显示了CPU 6。在此测试期间(3h17m),所有其他处理器都处于空闲状态)
从图中可以看到,当加载高峰到达内核代码中的所有处理时间时。所花费的时间主要用于延迟过程调用(最大16.8%)和处理中断(最大8.5%)。看起来有某种延迟的清理发生了,但我们不知道它会是什么。
据我们所知,它只发生在W2K3E-64上。
这种情况发生在不同的硬件上(HS21、HS22、HS22V、HP DL380)。
在Windows 2008上运行测试应用程序会在更小的程度上演示这个问题(更频繁,但驼峰更小)。
我们怎样才能解决这个问题,或者下一步应该在哪里寻找呢?
示例中的实际代码:
void handle_receive_from(const boost::system::error_code& error,
size_t bytes_recvd)
{
if (!error)
{
++m_receivedPackets;
m_receivedBytes += bytes_recvd;
m_last64TotalBytes += bytes_recvd;
if ( ( m_receivedPackets & 0x3F ) == 0 )
{
printf( "Received %u bytes in %u packets. The average size of the last 64 packets was %u bytes, and the last byte received was %x.\n",
m_receivedBytes, m_receivedPackets, m_last64TotalBytes / 64, m_buffer[ bytes_recvd - 1 ] );
m_last64TotalBytes = 0;
}
m_socket.async_receive_from(
boost::asio::buffer(m_buffer, max_length), m_senderEndpoint,
boost::bind(&receiver::handle_receive_from, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
std::cerr << "An error occurred when performing an asyncronous read." << std::endl;
m_socket.get_io_service().stop();
}
}发布于 2012-04-28 20:44:11
“看起来有某种延迟的清理发生了,但我们不知道会发生什么。”
这可能是垃圾收集,但我不确定垃圾收集是否显示为特权时间。如果这是一个.NET应用程序,您可以查看.NET CLR Memory性能计数器(尤其是Gen 2非常昂贵)。
在这种情况下,猜测可能出现的问题似乎有点倒退。你最好的选择是分析你的应用程序,看看它在做什么,看看应用程序调用了什么。您可能只需使用过程监视器来查看系统就可以逃脱。
发布于 2012-05-06 15:30:22
我假设系统正在接收多播数据包。您能否尝试阻止它接收数据包并查看是否看到了相同的问题?
加入多播组,但不监听数据包又如何?
你说它发生在不同的系统上,但是实际的NIC硬件呢?可能在不同的系统上是一样的。
更新:如果所有的系统都在使用Broadcom,那么问题可能就是NIC的问题。尤其是,微软提供的Broadcom驱动程序很糟糕;Broadcom网站上的驱动程序要好得多。
发布于 2012-05-09 03:13:33
您可以查看两件事:线程量和导致DPC (延迟过程调用)的原因。
线程量很容易寻址(可能是一条红鲱鱼,但也可以检查一下);
最有可能的背景服务被选中,尝试选择程序。这将减少中断之间的时间量,并允许在处理器上以相同的时间运行更多的线程。您会得到更多的中断,但处理时间更短。
延迟的过程调用更难诊断;
正如@wfaulk所述,这通常指向驱动程序问题。有一个名为DPC延迟检查器的方便工具可以帮助您诊断这些问题。尽管这种情况发生在多个硬件平台上,但它们仍然可能共享一个共同的驱动程序。运行DPC检查程序并按照其站点上的说明操作。
三个后续问题:
https://serverfault.com/questions/383959
复制相似问题