并行扩展

我有一个具有大量IO操作的应用程序,例如文件复制,压缩和移动文件系统周围的文件,复制到备份服务器。

我将此程序构建为单线程。 它运行2分钟。

我使用Parallel扩展并使用Task构建了该程序的另一个版本,它几乎在2分钟内运行。

换句话说,由于IO很大,我没有看到使用Parallels带来的性能提升。

如果我将应用程序部署到刀片服务器,我会得到相同的结果吗?

刀片服务器是否比我的工作站更快/更多地处理IO?

将Parallels与IO绑定应用程序一起使用没有任何好处吗?

如果您所做的只是在系统中复制或移动文件,那么TPL提供的并行性对您没有多大帮助。 例如,移动实际上不使用任何CPU,它只是更改磁盘目录记录结构中的文件位置。

文件压缩是另一回事。 在这里,您将加载数据并使用CPU对其进行压缩,然后再将其保存到磁盘。 您可以使用管道或并行循环以更有效的方式加载/压缩/保存数据。 而不是让一个线程工作压缩每个文件,你可以有多个线程处理不同的文件。

以下代码按顺序压缩文件加载,然后并行压缩。 我在i7 920和intel X25 SSD上获得以下时间,压缩329张JPG图像,总计800Mb数据。

顺序:39901ms

平行:12404ms

class Program { static void Main(string[] args) { string[] paths = Directory.GetFiles(@"C:\temp", "*.jpg"); DirectoryInfo di = new DirectoryInfo(@"C:\temp"); Stopwatch sw = new Stopwatch(); sw.Start(); foreach (FileInfo fi in di.GetFiles("*.jpg")) { Compress(fi); } sw.Stop(); Console.WriteLine("Sequential: " + sw.ElapsedMilliseconds); Console.WriteLine("Delete the results files and then rerun..."); Console.ReadKey(); sw.Reset(); sw.Start(); Parallel.ForEach(di.GetFiles("*.jpg"), (fi) => { Compress(fi); }); sw.Stop(); Console.WriteLine("Parallel: " + sw.ElapsedMilliseconds); Console.ReadKey(); } public static void Compress(FileInfo fi) { using (FileStream inFile = fi.OpenRead()) { if ((File.GetAttributes(fi.FullName) & FileAttributes.Hidden) != FileAttributes.Hidden & fi.Extension != ".gz") { using (FileStream outFile = File.Create(fi.FullName + ".gz")) { using (GZipStream Compress = new GZipStream(outFile, CompressionMode.Compress)) { inFile.CopyTo(Compress); } } } } } } 

有关压缩代码,请参见如何:压缩文件

如果您在一台物理设备上移动文件,那么向同一台设备发出多个并行IO请求时,您将不会看到太多的性能优势。 该设备已经比CPU慢了许多个数量级,因此并行发出的多个请求仍然排列在设备上逐个处理。 您的并行代码正在被序列化,因为它们都访问了一次无法真正处理多个请求的同一设备。

如果您的磁盘控制器实现“电梯搜索”,“分散 – 聚集”或其他无序操作,您可能会看到使用并行代码的微小性能改进,但是性能差异相对较小。

你应该在文件I / O中找到更有价值的性能差异,就是当你在许多不同的物理设备之间移动文件时。 您应该能够将磁盘A上的文件移动或复制到磁盘A上的其他位置,同时还将磁盘B上的文件复制到磁盘C.对于许多物理设备,您没有所有并行请求堆叠等待一个设备来填充所有请求。

您可能会看到与网络I / O类似的结果:如果所有内容都通过一个以太网卡/网段,您将无法实现与多个以太网卡和多个网段一起使用时的并行性。

我认为并行扩展的优势可能对CPU操作有重大影响。 Donnu它应该如何影响IO tho。

这完全取决于您是CPU绑定还是IO绑定。 我建议做一些性能测试,看看你的脖子在哪里。

如果您发现正在移动并压缩大量文件(对于不同的磁盘,因为在同一磁盘上移动只是一个FAT表更改),您可能希望查看实现在移动时压缩的流式文件移动器。 这可以节省移动后重读文件的额外IO。 我用移动和校验和完成了这个,在我的例子中是一个巨大的性能提升。

希望这可以帮助。

我有一个在WinForms中实现的应用程序,它在大约5分钟内处理大约7,800个URL(下载URL,解析内容,查找特定的数据片段,如果找到它寻找的内容,则对该数据进行一些额外的处理。

这个特定的应用程序运行需要26到30分钟才能运行,但是通过将代码更改为TPL(.NET v4.0中的任务并行库),它只需执行5个。计算机是带有双四核的Dell T7500工作站Xeon处理器(3 GHz),运行24 GB RAM和Windows 7 Ultimate 64位版本。

虽然,它与您的情况不完全相同,但这也是非常密集的IO。 关于TPL的文档声明它最初是为处理器绑定问题集而设想的,但这并不排除在IO情况下使用它(正如我的应用程序向我演示的那样)。 如果你有至少4个内核并且你没有看到你的处理时间显着下降那么你可能有其他实施问题阻止TPL真正有效(锁,硬盘驱动器项等)。 “使用Microsoft .NET进行并行编程”一书帮助我理解了“如何”修改代码以真正利用所有这些function。

值得一看我的意见。