当前位置: 首页 > 编程语言 > C#

CPU没有被充分利用,由于阻塞I-O?分享

时间:2023-04-10 20:43:48 C#

CPU未充分利用。由于阻塞I/O?我试图在C#服务器应用程序中找到未充分利用的瓶颈。我认为这可能是由于磁盘I/O性能不佳所致,与应用程序本身无关,但我无法从这个假设中得出事实。应用程序从本地MSMQ队列读取消息,对每条消息进行一些处理,并在处理完消息后,将响应消息发送到另一个本地MSMQ队列。我正在使用异步循环从队列中读取消息,尽快将它们出列并安排它们使用Task.Run开始处理每条消息(不要等待此Task.Run...只是追加一个continuationonlyWrongrecorderror)。每条消息都是并发处理的,即无需等待消息完全处理后再处理下一条消息。在处理消息结束时,我使用MessageQueue的Send方法(不知何故异步但不是真的,因为它必须在返回之前等待磁盘写入-请参阅System.Messaging-为什么MessageQueue不提供发送的异步版本)。对于基准测试,我将100K条消息放入队列中(100K条消息的总大小约为100MB),然后启动程序。在我的两台电脑上(一台SSDHD和另一台SATA2HD,i7CPU四核8逻辑处理器)——我在程序的生命周期内达到了~95%的CPU使用率(将100K消息输出列,处理它们并发送回复).消息尽可能快地出列,尽可能快地处理(这里涉及CPU),然后响应发送到不同本地队列的每条消息。现在在运行非HT双核CPU的VM上(不知道底层磁盘是什么,但它看起来比我的要少得多......在基准测试期间,使用Perfmon我可以看到avgdisksec/writearround10-15ms在这个VM上,虽然在我的个人机器上大约是2ms)当我运行同一个工作台时,我只能达到~55%CPU(当我在机器上运行同一个工作台时,没有响应消息发送到队列我达到~90%中央处理器)。我真的不明白这里出了什么问题。看起来很明显发送消息到队列是问题并且减慢了程序的全局处理(以及待处理消息的排队),但是为什么会认为我使用Task.Run开始处理每个出队消息并最终响应发送,我不希望CPU未得到充分利用。除非一个线程正在发送一条消息,同时阻止其他线程在等待返回(磁盘写入)时在同一核心上运行,在这种情况下,考虑到延迟比我个人计算机上的延迟高得多,但一个线程等待I/O不应阻止其他线程运行。我真的很想了解为什么我没有在这台机器上达到至少95%的CPU使用率。我盲目地说这是由于磁盘I/O性能不佳,但我仍然不明白为什么它会导致CPU未充分利用,因为我正在使用Task.Run并发运行处理。它也可能是一些与磁盘完全无关的系统问题,但考虑到MessageQueue.Send似乎是问题所在,并且这种方法最终将消息写入内存映射文件+磁盘,我看不出性能问题在哪里可能来自磁盘以外的地方。当然确实存在系统性能问题,因为程序在我自己的计算机上使用了CPU,但我需要找到VM系统的瓶颈以及为什么它会影响我的应用程序的并发/速度。有任何想法吗?要检查磁盘和/或CPU使用率是否低下,只有一种工具:WindowsPerformanceToolkit。有关如何使用它的示例,请参见此处。您应该从Windows8.1SDK(需要.NET4.5.1)获取最新版本,它提供了大部分功能,但Windows8SDK中的功能也很好。您可以获得图表%CPUUtilization和%DiskUtilization。如果其中一个是100%而另一个很低,那么您就找到了瓶颈。由于它是一个系统范围的分析器,您可以检查msmq服务是否正在使用光盘,或者您或其他人(例如,病毒扫描程序是一个常见问题)。您可以直接访问调用堆栈并检查哪个进程和线程实际上唤醒了应该全速运行的工作线程。然后你可以跳转到准备线程和进程并检查它在准备你的线程之前做了什么。这样你就可以直接验证是什么阻止了它。没有更多的猜测。您可以真正看到系统在做什么。要进一步分析CPUUsagePrecise视图中的以下列:然后向下钻取进程中的调用堆栈,以查看全速运行的线程中应该出现高等待(us)时间的位置。您可以向下钻取到单个事件,直到您不能再深入为止。然后你会在ReadyingProcess和ReadyingThreadId中看到值。转到那个进程/线程(它可以是你自己的)并重复这个过程,直到你结束一些涉及磁盘IO或休眠或长时间运行的设备驱动程序调用(如病毒扫描程序或vm驱动程序)的阻塞操作。如果磁盘I/O性能计数器没有出现异常高的情况,我接下来会查看管理程序级别。假设您正在运行完全相同的代码,使用VM会增加整个堆栈(CPU、RAM、磁盘)的延迟。您可以在管理程序级别调整CPU调度,看看这是否会增加CPU利用率。我也在考虑暂时使用RAMDisk进行性能测试。这将消除磁盘/SAN延迟,您可以查看是否解决了您的问题。以上就是C#学习教程:CPU没有被充分利用。由于阻塞I/O?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: