提问人:mjames 提问时间:5/14/2021 最后编辑:mjames 更新时间:5/14/2021 访问量:367
为什么当有其他任务运行时,dotnet 中的 IO 线程会急剧变慢?
Why does an IO Thread in dotnet dramatically slow down when there are other Tasks running?
问:
在我的机器上,使用以下代码读取 ~1.3GB 文件大约需要 ~13 秒:
static void ReadFileToBuffer()
{
var inputBuffer = new byte[1_300_000_000];
var ioStopwatch = new System.Diagnostics.Stopwatch();
ioStopwatch.Start();
int idx = 0;
using (var sr = new StreamReader(path))
{
while (sr.Peek() > -1)
{
//Could make this faster using ReadBlock
var data = sr.Read();
inputBuffer[idx] = (byte)data;
idx++;
}
}
ioStopwatch.Stop();
Console.WriteLine($"Write bytes To Buffer Read finished: {ioStopwatch.ElapsedMilliseconds}");
}
在单独的线程中运行此代码,然后等待它加入也需要 ~13 秒
public static void Main()
{
Thread t = new Thread(() =>
{
ReadFileToBuffer();
});
t.Priority = ThreadPriority.Highest;
t.Start();
t.Join();
}
但是,一旦我开始使用其他线程执行一堆非分配工作,IO 线程就会急剧减慢速度。此程序需要 30 秒才能在相同的输入文件上运行:
public static void Main()
{
var mainStopwatch = new System.Diagnostics.Stopwatch();
mainStopwatch.Start();
Thread t = new Thread(() =>
{
ReadFileToBuffer();
});
t.Priority = ThreadPriority.Highest;
t.Start();
Task[] taskArray = new Task[System.Environment.ProcessorCount-4];
var dummy_arr = new string[10000].Select((e, i) => i).ToArray();
long idx = 0;
bool run = true;
for (int i = 0; i < taskArray.Length; i++)
{
taskArray[i] = Task.Factory.StartNew(() =>
{
while (run)
{
//Do some dummy CPU bound work that doesn't allocate
var myIdx= System.Threading.Interlocked.Increment(ref idx);
dummy_arr[myIdx % 10000] = dummy_arr[myIdx % 10000].GetHashCode();
}
});
}
t.Join();
run = false;
mainStopwatch.Stop();
Console.WriteLine($"Full Program {mainStopwatch.ElapsedMilliseconds} - dummy work ran {idx} times");
}
有谁知道为什么会这样,可以做些什么?
我对“为什么”特别感兴趣。线程调度器是否不擅长不理会 IO 线程?
- DotNet Core 3.1
- Windows 10 版本 10.0.19042 内部版本 19042
- 已安装的物理内存 (RAM) 16.0 GB
- 处理器 AMD Ryzen 5 1600X 六核处理器, 3600 Mhz, 6 核, 12 逻辑处理器
- NVMe 三星 SSD 960 SCSI
答: 暂无答案
评论