我们有一台运行自定义工作负载的Windows 2003 R2 Enterprise 64位服务器,这个服务器存在性能问题。 下面的削减版本遭受较小的驼峰,但它的质量是相同的。
我们已经把它简化为一个简单的小应用程序,无非是:
testing应用程序本身是Boost ASIO多播接收器示例的一个稍微修改版本,所以没有多less应该是错误的。 下面的实际代码(!)…
每当在负载下运行这个程序的时候,这个进程的CPU就会在内核代码中发生所有的处理:
(此处仅显示CPU 6,在此testing期间(3小时17分钟)所有其他处理器都处于空闲状态)
从图中可以看出,当负载峰值冲击时,所有的处理时间都发生在内核代码中。 花费的时间主要用于延迟程序调用(最大16.8%)和处理中断(最大8.5%)。 看起来有一些延迟清理发生,但我们不知道它可能是什么。
只要我们可以告诉它只在W2K3E-64上发生。
它发生在不同的硬件上(HS21,HS22,HS22V,HP DL380)。
在Windows 2008上运行testing应用程序可以将问题显示得更小(更多的是更小的峰值)。
我们如何解决这个问题,或者我们应该在下一步看看?
实例中的实际代码:
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(); } }
“看起来有一些延期清理发生,但我们不知道它可能是什么。”
这可能是垃圾收集,但我不确定垃圾收集显示为特权时间。 如果这是一个.NET应用程序,可以查看.NET CLR Memory性能计数器(第2代特别昂贵)。
为此,猜测可能的问题似乎有点倒退。 你最好的select是分析你的应用程序,看看它在做什么,看看应用程序正在做什么。 您可能只能使用Process Monitor来观看系统调用。
我假设系统正在接收组播数据包。 你可以试着阻止它接收数据包,看看你是否看到同样的问题?
那么join多播组,但不听包呢?
你说它发生在不同的系统上,但是实际的NIC硬件呢? 这些不同的系统可能是一样的。
更新:如果所有系统都使用Broadcom网卡,则可能是由于网卡问题。 微软提供的Broadcom驱动程序尤其糟糕; Broadcom网站上的那个更好。
你可以看两件事情:你的线程量和DPC(延迟过程调用)是什么造成的。
线程量子很容易解决(可能是一个红鲱鱼,但不妨检查一下);
最有可能的后台服务被选中,请尝试select程序。 这将减less中断之间的时间,并允许更多的线程在处理器上运行相同的时间。 你会得到更多的中断,但处理时间更less。
延迟程序调用有点难以诊断;
正如@wfaulk所说,这通常指向一个驱动程序问题。 有一个方便的工具称为DPC延迟检查器 ,将帮助您诊断这些问题。 即使这种情况发生在多个硬件平台上,它们仍然可能共享驱动程序。 运行DPC Checker并按照其网站上的说明进行操作。
三个后续问题:
你正在使用网卡吗? 他们使用TCP / IP协议栈来相互通信,并可能导致严重的DPC问题。
你的网卡是否支持TCP卸载? 启用了吗?
(黑暗中的完整镜头)您的testing服务器是域的一部分吗? GPO默认每90分钟刷新一次…