当前位置: 首页 > 编程语言 > C#

充分利用.NET任务并行库分享

时间:2023-04-10 17:16:11 C#

充分利用.NET任务并行库问题1.Parallel.For和Parallel.ForEach对于有序任务和无序任务哪个更好?我问的原因是我最近更新了一个串行循环,其中使用StringBuilder生成基于各种参数的SQL语句。结果是,与使用标准的foreach循环相比,SQL有点混乱(到了包含语法错误的地步),所以我的直觉是TPL不适合强制执行数据必须以临时顺序出现。问题2.TPL是否自动使用多核架构,我是否必须在执行前进行任何配置?我问这个问题的原因与我问的有关TPL操作的性能分析的问题有关。这个问题的答案让我明白TPL并不总是比标准串行循环更高效,因为应用程序可能无法访问多个内核,因此创建额外线程和循环的开销会导致标准串行循环的性能下降。我的直觉是TPL不适合执行数据必须按特定顺序出现的任务。正确的。如果您希望事情井然有序,您可能会误解“并行化”循环时会发生什么。TPL是否自动使用多核架构,我是否必须在执行前进行任何配置?请参阅msdn杂志上的以下文章:http://msdn.microsoft.com/en-us/magazine/cc163340.aspx使用此库,您可以轻松地在现有顺序代码中表达潜在的并行性,从而公开将运行的并行任务同时在所有可用的处理器上。如果必须对结果进行排序,那么为了并行化循环,您需要能够以任何顺序执行实际工作,然后对结果进行排序。根据情况的不同,这可能比一开始就连续工作更有效率,也可能没有。如果以任何顺序并行化工作的好处超过对结果进行排序的成本,那么它就是净收益。如果任务不够复杂,您的硬件不允许大量并行化,或者如果它不能很好地并行化(即由于数据依赖性导致大量等待),那么对结果进行排序可能需要更多时间(或更糟,即使没有排序,并行循环也会花费更长的时间,请参阅问题二),因此您不应该将其并行化。请注意,如果实际工作单元需要按特定顺序运行,而不仅仅是按特定顺序运行结果,那么您将无法对其进行并行化,或者您将无法以几乎同样高效的方式对其进行并行化.如果您没有正确同步对共享资源的访问,您实际上可能会得到错误的结果(就像您的情况一样)。为此,您需要记住,如果您实际上无法获得正确的结果,那么性能优化就毫无意义。您真的不需要担心TPL的硬件。您无需明确添加或限制任务。虽然有几种方法可以做到这一点,但几乎任何时候你做这样的事情都会损害性能。当您执行此类操作时,您就是在向TPL添加限制,因此它无法执行它想执行的操作。通常它比你更了解。您还可以在这里触及另一点,即并行循环通常需要更长的时间(您只是没有给出这种行为的可能原因)。通常,需要完成的实际工作很少,以至于创建线程、管理线程、处理上下文移动和根据需要同步数据可能比并行工作所能完成的工作更多。这就是为什么在决定并行化某些工作以确保它确实从中受益时实际进行大量测试很重要的原因。对于无序列表来说,这并没有好坏之分——你在#1中的问题是你对StringBuilder有一个共享依赖,这就是并行查询失败的原因。TPL擅长独立工作单位。即使这样,也可以使用一个简单的技巧来强制计算并行查询并在并行操作完成后保持结果的原始顺序。TPL和PLINQ在技术上是不同的;PLINQ使用TPL来实现其目标。也就是说,PLINQ会尝试检查您的架构并尽可能地构建集合的执行。TPL只是任务架构的包装器。由您决定创建任务的开销(大约1MB内存),以及执行任务的上下文切换开销是否大于简单地连续运行任务。关于第1点,如果你使用TPL,你不知道以何种顺序运行哪些任务。这就是平行和顺序的美妙之处。有一些方法可以控制事物的顺序,但您可能会失去并行性的好处。In2:TPL支持开箱即用的多核。但是使用多线程总是有开销的。调度器的负载增加,线程(上下文)切换不是免费的。为了保持数据同步以避免竞争条件,您可能需要一些锁定机制,这也会增加开销。使用TPL可以更轻松地制作快速并行算法,但仍然是一门艺术。显然TPL不是构建查询等有序集的好工具。如果要对一组项目执行一系列任务,可以使用BlockingCollection。任务可以并行执行,但保持组的顺序。上面的BlockingCollection类就是C#学习教程:充分利用.NET任务并行库共享的所有内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文来自网络收藏,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: