I / O并行性真的能提供如此多的性能吗?

时间:2014-02-12 22:11:45

标签: c# multithreading performance asynchronous io

stackoverflow上有很多问题:我应该使用多少IO线程? 答案是一个,如果CPU不是buisy,或者你将有开销。

我测试过我发现这根本不是真的,或者我的测试代码可能不对。让我们试试吧 使用.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:Async在5%
  • 上更快
  • RAID 0,Windows 8:Async在40%上更快。 (但为什么这么多?为什么控制器和内核不按预期进行并行化?)

我也尝试过不要使用标准文件。复制并只将文本写入文件usync .NET Async构造 - 相同的结果。

所以我得出一个结论,即最佳的concarancy水平应该通过自适应算法进行搜索。 2个同时发出的IO请求总是好于1.你同意这个吗?

3 个答案:

答案 0 :(得分:2)

IO操作将受IO限制,而不受CPU限制。 CPU操作将受CPU限制。

对于IO操作,不应使CPU资源最大化。如果这样做,则没有IO绑定操作,您有一个CPU绑定操作。

IO操作,如果通过正确的异步API公开,则不需要任何线程There is no thread。如果您只有同步API,那么您需要尽可能多的线程来保持任何IO介质满负荷。这可能是一个线程,两个或几百个。

如果您已经接近100%利用基于IO的资源(无论是硬盘,数据库,网络连接等),那么添加额外的线程也无济于事。事实上,它有时甚至会受到伤害。例如,硬盘针对顺序访问进行了大量优化。并行化通常会导致更多随机访问,这实际上会导致性能大幅下降。

答案 1 :(得分:2)

在一个磁盘上运行多个顺序IO流时,会得到随机IO。表现完全坦克。

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

你有4个文件,每个1GB。你的机器可能有> 4GB的RAM。

将文件大小增加10倍,性能将完全变为坦克。你会听到你的磁盘在所有磁盘搜索中疯狂地发出嘎嘎声。

使用进程监视器,您可以看到Windows(非常不幸)向交错的底层磁盘发出256KB IO。实现连续性能远远不够小。

我在这里重复一下我的评论:

  

我怀疑你的测量。每个试图在Windows资源管理器中复制多个大文件的人都知道并非如此。我们需要找出您的测量结果有什么问题,或者对您的设置有所了解。

换句话说,您的基准测试不是衡量您的想法。

答案 2 :(得分:0)

异步在RAID上要快得多,因为它利用了更多的设备并行性。只有非常快速的基于PCI-E的SSD才会有更多I / O线程为您提供更高性能的数字(以使PCI带宽饱和)。对于大多数具有更好I / O深度的东西(实际上发出更大的I / O)会让你获得更好的性能。