I/O并行性真的能提供这么多性能吗



关于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%。(但为什么这么多?为什么控制器和内核没有像预期的那样并行工作?)

我也试过不使用standart文件。复制文本并只将文本写入到usync.NETAsync构造的文件中—结果相同。

因此,我得出结论,最优连通度应采用自适应算法进行搜索。2个同时IO请求总是比1个好。你同意这一点吗?

当你在一个磁盘上运行多个顺序IO流时,你会得到随机IO。性能完全下降。

为什么这里不是这样?我怀疑你的文件足够小,可以放入内存/缓存。你所有的工作都受CPU限制。甚至写入也会延迟地刷新到磁盘。

您有4个1GB的文件。您的机器可能有>4GB的RAM。

将文件大小增加10倍,性能将完全下降。你会听到你的磁盘在所有磁盘搜索中疯狂地嘎嘎作响。

使用Process Monitor,您可以看到Windows(非常不幸)向交错的底层磁盘发出256KB IO。这对于实现顺序性能来说太小了。

我在这里重复我的评论:

我怀疑你的衡量标准。每个试图在Windows资源管理器中同时复制多个大文件的人都知道事实并非如此。我们需要找出您的测量值有什么问题,或者您的设置有什么特别之处。

换句话说,你的基准并不是在衡量你认为它是什么。

IO操作将绑定到IO,而不是CPU。CPU操作将受到CPU限制。

对于IO操作,不应该使CPU的资源达到最大。如果你这样做了,你就没有一个IO绑定的操作,你有一个CPU绑定的操作。

如果IO操作是通过适当的异步API公开的,则不需要任何线程。没有线程。如果您只有同步API,那么您需要尽可能多的线程来保持任何IO介质的满容量。这可能是一根线,两根线,或者几百根线。

一旦你达到了基于IO的资源(无论是硬盘、数据库还是网络连接等)接近100%利用率的地步,添加额外的线程也无济于事。事实上,它有时甚至会很痛。例如,硬盘针对顺序访问进行了大量优化。并行化通常会导致更多的随机访问,这实际上会导致性能显著降低。

Async在RAID上要快得多,因为它利用了更多的设备并行性。只有对于非常快速的基于PCI-E的SSD,更多的I/O线程才能为您带来更高的性能数字(使PCI带宽饱和)。对于大多数情况来说,拥有更好的I/O深度(实际上是更大的I/O)将获得更好的性能。

最新更新