草庐IT

C# I/O Parallelism 确实提高了 SSD 的性能?

coder 2023-07-12 原文

我在 SO 上阅读了一些答案(对于 example),其中有人说并行性不会提高性能(可能在读取 IO 中)。

但我创建了一些测试,这些测试表明 WRITE 操作也快得多。

阅读测试:

我用虚拟数据创建了随机的 6000 个文件:

让我们尝试在没有并行性的情况下阅读它们:

var files =
    Directory.GetFiles("c:\\temp\\2\\", "*.*", SearchOption.TopDirectoryOnly).Take(1000).ToList();

    var sw = Stopwatch.StartNew();
    files.ForEach(f => ReadAllBytes(f).GetHashCode()); 
    sw.ElapsedMilliseconds.Dump("Run READ- Serial");
    sw.Stop(); 


    sw.Restart();
    files.AsParallel().ForAll(f => ReadAllBytes(f).GetHashCode()); 
    sw.ElapsedMilliseconds.Dump("Run READ- Parallel");
    sw.Stop();

结果 1:

Run READ- Serial 595

Run READ- Parallel 193

结果 2:

Run READ- Serial 316

Run READ- Parallel 192

写入测试:

要创建 1000 个随机文件,每个文件为 300K。 (我清空了之前测试的目录)

var bytes = new byte[300000];
Random r = new Random();
r.NextBytes(bytes);
var list = Enumerable.Range(1, 1000).ToList();

sw.Restart();
list.ForEach((f) => WriteAllBytes(@"c:\\temp\\2\\" + Path.GetRandomFileName(), bytes)); 
sw.ElapsedMilliseconds.Dump("Run WRITE serial");
sw.Stop();

sw.Restart();
list.AsParallel().ForAll((f) => WriteAllBytes(@"c:\\temp\\2\\" + 
Path.GetRandomFileName(), bytes)); 
sw.ElapsedMilliseconds.Dump("Run  WRITE Parallel");
sw.Stop();

结果 1:

Run WRITE serial 2028

Run WRITE Parallel 368

结果 2:

Run WRITE serial 784

Run WRITE Parallel 426

问题:

结果让我大吃一惊。很明显,出乎所有人的意料(尤其是 WRITE 操作)- 并行性的性能更好,但 IO 操作。

并行结果如何/为什么更好?似乎 SSD 可以与线程一起工作,并且在 IO 设备中一次运行多个作业时没有/更少瓶颈。

注意,我没有用 HDD 测试它(我很高兴有 HDD 的人可以运行测试。)

最佳答案

基准测试是一门棘手的艺术,您只是没有衡量您认为的自己。从测试结果来看,它实际上不是 I/O 开销有些明显,为什么单线程代码第二次运行时速度更快?

您没有指望的是文件系统缓存 的行为。它在 RAM 中保留磁盘内容的副本。这对多线程代码测量有特别大的影响,它根本不使用任何 I/O。。简而言之:

  • 如果文件系统缓存有数据副本,则读取来自 RAM。它以内存总线速度运行,通常约为 35 GB/秒。如果它没有副本,则读取会延迟到磁盘提供数据为止。它不仅读取请求的簇,还读取磁盘上整个柱面的数据。

  • 直接写入 RAM,非常完成。当程序继续执行时,该数据在后台延迟写入磁盘,并进行了优化以最大限度地减少柱面顺序中的写入磁头移动。只有当没有更多 RAM 可用时,写入才会停止。

实际缓存大小取决于安装的 RAM 量和运行进程对 RAM 的需求。一个非常粗略的指导方针是,您可以在具有 4GB RAM 的机器上指望 1GB,在具有 8GB RAM 的机器上指望 3GB。它在资源监视器的内存选项卡中可见,显示为“缓存”值。请记住,它是高度可变的。

足以理解您所看到的内容,并行测试从已经读取所有数据的串行测试中受益匪浅。如果您编写的测试是先运行并行测试,那么您会得到截然不同的结果。只有当缓存是冷的时,您才能看到由于线程导致的性能损失。您必须重新启动机器以确保该条件。或者先读取另一个非常大的文件,大到足以从缓存中清除有用数据。

只有当您先验地了解您的程序只读取刚刚写入的数据时,您才能安全地使用线程而不会有性能损失的风险。这种保证通常很难获得。它确实存在,一个很好的例子是 Visual Studio 构建您的项目。编译器将构建结果写入 obj\Debug 目录,然后 MSBuild 将其复制到 bin\Debug。看起来很浪费,但事实并非如此,因为文件在缓存中很热,所以复制总是会很快完成。缓存还解释了 .NET 程序的冷启动和热启动之间的区别,以及为什么使用 NGen 并不总是最好的。

关于C# I/O Parallelism 确实提高了 SSD 的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44383532/

有关C# I/O Parallelism 确实提高了 SSD 的性能?的更多相关文章

  1. 程序员如何提高代码能力? - 2

    前言作为一名程序员,自己的本质工作就是做程序开发,那么程序开发的时候最直接的体现就是代码,检验一个程序员技术水平的一个核心环节就是开发时候的代码能力。众所周知,程序开发的水平提升是一个循序渐进的过程,每一位程序员都是从“菜鸟”变成“大神”的,所以程序员在程序开发过程中的代码能力也是根据平时开发中的业务实践来积累和提升的。提高代码能力核心要素程序员要想提高自身代码能力,尤其是新晋程序员的代码能力有很大的提升空间的时候,需要针对性的去提高自己的代码能力。提高代码能力其实有几个比较关键的点,只要把握住这些方面,就能很好的、快速的提高自己的一部分代码能力。1、多去阅读开源项目,如有机会可以亲自参与开源

  2. Ruby 的数字方法性能 - 2

    我正在使用Ruby解决一些ProjectEuler问题,特别是这里我要讨论的问题25(Fibonacci数列中包含1000位数字的第一项的索引是多少?)。起初,我使用的是Ruby2.2.3,我将问题编码为:number=3a=1b=2whileb.to_s.length但后来我发现2.4.2版本有一个名为digits的方法,这正是我需要的。我转换为代码:whileb.digits.length当我比较这两种方法时,digits慢得多。时间./025/problem025.rb0.13s用户0.02s系统80%cpu0.190总计./025/problem025.rb2.19s用户0.0

  3. ruby - Ruby 性能中的计时器 - 2

    我正在寻找一个用ruby​​演示计时器的在线示例,并发现了下面的代码。它按预期工作,但这个简单的程序使用30Mo内存(如Windows任务管理器中所示)和太多CPU有意义吗?非常感谢deftime_blockstart_time=Time.nowThread.new{yield}Time.now-start_timeenddefrepeat_every(seconds)whiletruedotime_spent=time_block{yield}#Tohandle-vesleepinteravalsleep(seconds-time_spent)iftime_spent

  4. ruby-on-rails - 如果条件与 &&,是否有任何性能提升 - 2

    如果用户是所有者,我有一个条件来检查说删除和文章。delete_articleifuser.owner?另一种方式是user.owner?&&delete_article选择它有什么好处还是它只是一种写作风格 最佳答案 性能不太可能成为该声明的问题。第一个要好得多-它更容易阅读。您future的自己和其他将开始编写代码的人会为此感谢您。 关于ruby-on-rails-如果条件与&&,是否有任何性能提升,我们在StackOverflow上找到一个类似的问题:

  5. ruby - 如何找到我的 Ruby 应用程序中的性能瓶颈? - 2

    我编写了一个Ruby应用程序,它可以解析来自不同格式html、xml和csv文件的源中的大量数据。我如何找出代码的哪些区域花费的时间最长?有没有关于如何提高Ruby应用程序性能的好资源?或者您是否有任何始终遵循的性能编码标准?例如,你总是用加入你的字符串吗?output=String.newoutput或者你会使用output="#{part_one}#{part_two}\n" 最佳答案 好吧,有一些众所周知的做法,例如字符串连接比“#{value}”慢得多,但是为了找出您的脚本在哪里消耗了大部分时间或比所需时间更多,您需要进行分

  6. STM32的HAL和LL库区别和性能对比 - 2

    LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L

  7. ruby - GC.disable 的任何性能缺点? - 2

    是否存在GC.disable会降低性能的情况?只要我使用的是真正的RAM而不是交换内存,就可以这样做吗?我正在使用MRIRuby2.0,据我所知,它是64位的,并且使用的是64位的Ubuntu:ruby2.0.0p0(2013-02-24revision39474)[x86_64-linux]Linux[redacted]3.2.0-43-generic#68-UbuntuSMPWedMay1503:33:33UTC2013x86_64x86_64x86_64GNU/Linux 最佳答案 GC.disable将禁用垃圾回收。像rub

  8. ruby-on-rails - Rails with angular 与 Rails pure(查看性能) - 2

    我尝试在Internet上搜索有关使用angularJS进入RubyonRails项目与RubyonRailspure的View性能的信息。我的问题是因为2个月前我开始使用纯AngularJS,现在我需要将AngularJS集成到一个新项目中,但需要展示使用带有RubyonRails的AngularJS呈现View的性能如何,并消除对RubyonRails的负担.例如:带Rails的Angular:使用RubyonRails获取数据(从数据库或GET请求),将信息发送到file.js.erb并使用AngularJS操作数据并显示带有解析数据的View。纯粹的Rails:(自然流程)使用

  9. ruby-on-rails - 在 Rails 3 应用程序中使用 require_dependency 对性能有何影响? - 2

    我觉得我理解require和require_dependency之间的区别(来自Howarerequire,require_dependencyandconstantsreloadingrelatedinRails?)。但是,我想知道如果我使用一些不同的方法(参见http://hemju.com/2010/09/22/rails-3-quicktip-autoload-lib-directory-including-all-subdirectories/和Bestwaytoloadmodule/classfromlibfolderinRails3?)来加载所有文件会发生什么,所以我们:

  10. arrays - Ruby 中的并行分配性能 - 2

    设置一个临时变量来交换数组中的两个元素似乎比使用并行赋值更有效。谁能帮忙解释下?require"benchmark"Benchmark.bmdo|b|b.reportdo40000000.times{array[1],array[2]=array[2],array[1]}endendBenchmark.bmdo|b|b.reportdo40000000.timesdot=array[1]array[1]=array[2]array[2]=tendendend结果:usersystemtotalreal4.4700000.0200004.490000(4.510368)usersyste

随机推荐