【发布时间】:2014-03-11 13:04:24
【问题描述】:
stackoverflow 上有很多问题:IO 应该使用多少线程? 答案是一个,如果 CPU 不忙,或者你会有开销。
我测试我发现这根本不是真的,或者我的测试代码可能是错误的。让我们试试 使用 .NET 同步和异步复制大文件:
class Program
{
const string UserDirectory = @"C:\testDir\";
const string sourceFile1 = UserDirectory + "1.rar";
const string sourceFile2 = UserDirectory + "2.rar";
const string dstFile1 = UserDirectory + "1copy.rar";
const string dstFile2 = UserDirectory + "2copy.rar";
static void Main(string[] args)
{
Clear();
var watch = Stopwatch.StartNew();
StdCopySync();
Console.WriteLine("Standart copy Sync complited in {0} ms", watch.ElapsedMilliseconds);
Clear();
Thread.Sleep(1000);
watch.Restart();
StdCopyAsync();
Console.WriteLine("Standart copy Async complited in {0} ms", watch.ElapsedMilliseconds);
}
private static void Clear()
{
File.Delete(dstFile1);
File.Delete(dstFile2);
}
private static void StdCopySync()
{
File.Copy(sourceFile1, dstFile1);
File.Copy(sourceFile2, dstFile2);
}
private static void StdCopyAsync()
{
Task t1 = new Task(() =>
{
File.Copy(sourceFile1, dstFile1);
});
Task t2 = new Task(() =>
{
File.Copy(sourceFile2, dstFile2);
});
t1.Start();
t2.Start();
Task.WaitAll(new List<Task>() { t1, t2 }.ToArray());
}
}
平均结果让我大吃一惊。 (5 个测量,sourceFile1 与 sourceFile2 相同,大小接近 1GB)
- 单硬盘,Windows 7:异步速度提高 16%
- SSD,Windows 8:异步速度提高 5%
- RAID 0,Windows 8:异步速度提高 40%。 (但为什么这么多?为什么控制器和内核没有按预期并行工作?)
我也试过不使用标准文件。复制文本并将其写入文件 usync .NET Async 构造 - 结果相同。
所以我得出一个结论,最佳一致性水平应该通过自适应算法进行搜索。并且 2 个同时 IO 请求总是比 1 个更好。你同意吗?
【问题讨论】:
-
请注意,异步与线程无关。
-
@SLaks 是的,谢谢。我的意思是同时的 IO 请求。已更正。
-
在做IO的时候,需要做的就是保持磁盘硬件忙于读/写。线程对此无济于事。
-
我怀疑你的测量结果。每个尝试在 Windows 资源管理器中同时复制多个大文件的人都知道事实并非如此。我们需要找出您的测量有什么问题或您的设置有什么特别之处。
-
这些测试是出了名的不可靠,根本不测试 I/O 速度。只是内存总线带宽,由文件系统缓存使用。非常快,只是内存到内存的复制。在每次测试运行之前,首先使用 SysInternals 的 RAMMap 实用程序刷新缓存。并且确保只使用单个线程进行测试,当线程开始争夺磁盘并强制它来回压缩时,使用多个线程非常会降低速度。尽管 Windows 中的文件复制引擎尝试对此做一些事情,但版本很重要。
标签: c# multithreading performance asynchronous io