gpt4 book ai didi

c# - 如何在运行时判断我的进程是 CPU 密集型还是 I/O 密集型

转载 作者:行者123 更新时间:2023-12-02 09:19:51 25 4
gpt4 key购买 nike

我有一个程序,可以通过 TCP 链接发送数据。我正在使用异步读取和写入磁盘和网络。如果我输入 DeflateStream在中间(所以我在写入网络链接之前进行压缩,并在收到数据并将其写入磁盘时进行解压缩)我在压缩方面受 CPU 限制。这导致我的最大传输速率约为 300 KB/s。但是,如果删除压缩步骤,我现在将 I/O 绑定(bind)到磁盘,并且获得 40,000 KB/s 的传输速率。

在严格的 LAN 条件下,我的 I/O 上限将始终超过 300 KB/s,但是如果我的程序通过互联网运行,我的网络 IO 限制很可能低于 300 KB/s。

我想检测我是否受到 I/O 限制并且我的网络/磁盘链接是限制因素,或者我是否受到 CPU 限制并且压缩行为是最拖慢我速度的因素。如何检测我的程序在运行时是否受到 CPU 或 I/O 的限制,以便我可以切换协议(protocol)并获得最佳的传输速率?

private static void SendFile(string filename, NetworkStream stream, int sendBufferSize)
{
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 4096, FileOptions.Asynchronous | FileOptions.SequentialScan))
using (var ds = new DeflateStream(stream, CompressionMode.Compress))
{
StreamUtilities.CopyAsync(fs, ds, sendBufferSize);
}
}

public static void CopyAsync(Stream sourceStream, Stream destStream, int bufferSize = 4096)
{
Byte[] bufferA = new Byte[bufferSize];
Byte[] bufferB = new Byte[bufferSize];

IAsyncResult writeResult = null;
IAsyncResult readResult = null;

bool readBufferA = false;
int read;

readResult = sourceStream.BeginRead(bufferA, 0, bufferA.Length, null, null);
//Complete last read
while ((read = sourceStream.EndRead(readResult)) > 0)
{
if (readBufferA)
{
PerformOperations(sourceStream, destStream, bufferA, bufferB, ref readResult, ref writeResult, read);
}
else
{
PerformOperations(sourceStream, destStream, bufferB, bufferA, ref readResult, ref writeResult, read);
}

//Flip the bit on the next buffer
readBufferA = !readBufferA;
}
if (writeResult != null)
destStream.EndWrite(writeResult);
}

private static void PerformOperations(Stream sourceStream, Stream destStream, Byte[] readBuffer, Byte[] writeBuffer, ref IAsyncResult readResult, ref IAsyncResult writeResult, int bytesToWrite)
{
//Start next read
readResult = sourceStream.BeginRead(readBuffer, 0, readBuffer.Length, null, null);

//End previous write
if (writeResult != null)
destStream.EndWrite(writeResult);
writeResult = destStream.BeginWrite(writeBuffer, 0, bytesToWrite, null, null);
}

最佳答案

一种选择是将这两个方面分离到生产者/消费者队列中:压缩器将 block 写入队列中,然后由仅执行 ​​IO 的线程使用。

这样:

  • 您可以在 IO 发生时进行压缩,而无需进入异步 IO
  • 您可以检测您是否受 CPU 限制(队列通常为空,或短暂地有 1 个 block )或 IO 限制(当压缩速度快于发送速度时,队列逐渐变大)
  • 通过一些工作,您可以多线程压缩;您需要跟踪 block 顺序,但这应该是可行的。

关于c# - 如何在运行时判断我的进程是 CPU 密集型还是 I/O 密集型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13573368/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com