“并行”执行与“并行”执行之间的区别?


107

是什么方面的区别并发并行执行?我从来没有完全能够理解这种区别。

该标签将并发定义为同时运行两个进程的方式,但是我认为并行性是完全相同的事情,即:可能在单独的处理器上运行的单独的线程或进程。

另外,如果我们考虑使用异步I / O之类的东西,那么我们是在处理并发性还是并行性?


27
简而言之-并发:许多不同的操作会同时发生。并行:同一操作一次分解成几个小块。
Oded

3
@Oded,我理解这些词的意思,但是我无法理解其中的含义。你有一个具体的例子吗?
blz 2013年

7
@Oded,我真的不同意您的看法,在它们的定义(通用的或适用于编程的定义)中,“并发”和“并行”的概念均未提及有关操作数或“大小”的任何内容。
Shivan Dragon 2013年

2
当您说“小块”时,@ Oded。
Avner Shahar-Kashtan

2
@Oded:是的,但这似乎是您和ShivanDragon之间误解的根源。
Avner Shahar-Kashtan

Answers:


97

并发和并行是两个相关但截然不同的概念。

并发本质上意味着任务A和任务B都需要彼此独立发生,并且A开始运行,然后B在A完成之前开始。

有多种完成并发的方法。其中之一就是并行性-让多个CPU同时处理不同的任务。但这不是唯一的方法。另一个是通过任务切换,它的工作方式如下:任务A工作到某个点,然后工作的CPU停止并切换到任务B,处理一段时间,然后再切换回任务A。时间片足够小,即使实际上它们实际上是由多任务CPU串行处理的,对于用户来说,这似乎都是并行运行的。


4
情况B是异步IO的工作方式,不是吗?
blz 2013年

6
@blz:是的。这也是抢先式多任务处理的工作方式。主要区别在于,在异步IO上,程序决定放弃其时间并告诉CPU处理其他事情,而在抢占式多任务处理中,如果运行的线程在足够长的时间内没有自愿放弃CPU,则操作系统会抢占它。
梅森惠勒2013年

1
最好的解释
Konrad

@MasonWheeler:如果我们只有1个CPU,那么我们只能有并发性,没有并行性。对?并行性可以通过1个以上的CPU来实现。对?如果是正确的,并且我们只有1个CPU,那么Java 8中的Streams毫无用处。
艾尼丝米塔尔

1
关于前几点。至于最后一个,并行性是您从Streams获得的唯一好处吗?我不是Java开发人员,但我的印象是Java Streams大致等同于LINQ,并且在表达性和易于开发方面具有真正的优势。
梅森惠勒

37

这两个概念是相关的,但有所不同。

并发意味着在同一时间范围内发生两个或多个计算,并且它们之间通常存在某种依赖关系。

并行是指同时进行两个或多个计算。

大胆地说,并发描述了一个问题(两件事需要一起发生),而并行描述了一个解决方案(两个处理器内核用于同时执行两件事)。

并行是实现并发的一种方法,但不是唯一的方法。另一个流行的解决方案是交错处理(也称为协程):将两个任务分解为原子步骤,然后在两者之间来回切换。

迄今为止,最不知名的非并行并发示例是JavaScript的工作方式:只有一个线程,并且任何异步回调都必须等到之前的代码块执行完毕。要知道这一点很重要,因为它可以确保您编写的任何函数都是原子函数-在返回之前,任何回调都不能中断它。但这也意味着“忙循环”将不起作用-您无法设置超时然后循环直到它触发为止,因为循环将阻止超时回调的执行。


8
你说,Concurrency means that two or more calculations happen within the same time frame, and there is usually some sort of dependency between them.但是写那个接受答案的用户说Concurrency means, essentially, that task A and task B both need to happen independently of each other。那么结论是什么?
nbro

你能解释为什么JavaScript的模型是并发的吗?根据并发的定义,应在同一时间范围内进行两次或多次计算。但是在JavaScript中,使用单个队列对计算进行了顺序排序。
damluar '16

4
我所说的“在同一时间范围内”并不一定意味着“同时”,只是它们发生的整个时间范围是重叠的。这可以并行实现(例如,两个处理器内核,每个执行一个任务),但是也可以通过完全序列化执行来实现(首先执行任务1,记住结果,然后执行任务2,然后报告两者) ,或者将两者切碎并交织在一起。后者是JS所做的。
tdammers '16

9

我相信这个答案比现有答案更正确,对其进行编辑将改变其本质。我试图链接到各种资源或Wikipedia页面,以便其他人可以确认正确性。


并发:系统的一种属性,使程序,算法或问题的各个单元可以无序或部分顺序执行,而不会影响最终结果1 2

一个简单的例子是连续添加:

0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = 45

由于加法的交换性质,可以在不影响正确性的情况下重新排列这些顺序。以下安排将得出相同的答案:

(1 + 9) + (2 + 8) + (3 + 7) + (4 + 6) + 5 + 0 = 45

在这里,我将数字分为几对,总计为10,这使我更容易得出正确的答案。

并行计算:一种计算类型,其中许多计算或过程的执行同时进行3 4。因此,并行计算利用并发性来同时执行程序,算法或问题的多个单元。

继续以连续加法为例,我们可以并行执行总和的不同部分:

Execution unit 1:  0 + 1 + 2 + 3 + 4 = 10
Execution unit 2:  5 + 6 + 7 + 8 + 9 = 35

然后最后,我们对每个工人的结果求和10 + 35 = 45

同样,这种并行性仅是可能的,因为连续的添加具有并发性。

但是,并发不仅可以被并行性利用。考虑在单核系统上抢占:一段时间后,系统可能会在多个运行中的进程上取得进展,而其中任何一个都没有完成。确实,您的异步I / O示例是并发的常见示例,不需要并行处理。


混乱

上面是相对简单的。我怀疑人们会感到困惑,因为字典定义不一定与上面概述的内容匹配:

  • 并发:同时发生或同时存在或并存5
  • 并发:两个或多个事件或情况同时发生或同时存在的事实从google搜索:“ define:concurrency”

字典将“并发”定义为出现的事实,而在计算语言中的定义是程序,属性或系统的潜在属性。尽管相关,但这些东西并不相同。


个人建议

我建议在确保或预期同时执行时使用术语“并行”,而在不确定是否要使用同时执行时不建议使用“并发”。

因此,我将描述在多核上并行模拟喷气发动机。

我将Makefiles描述为并发的一个例子。Makefile声明每个目标的依赖性。当目标依赖于其他目标时,这将创建部分排序。全面,正确地定义了关系和配方后,这将建立并发属性:存在部分顺序,以便可以重新安排某些任务的顺序,而不会影响结果。同样,可以利用此并发性同时构建多个规则,但是无论是否采用并行性,并发性都是Makefile的属性。


6

并发执行是并行执行的一般形式。例如,并行程序也可以称为并发,但是反向不是真的。

  1. 可以在单个处理器上并发执行(多个线程,由调度程序管理)
  2. 在单个处理器上不能并行执行,而在多个处理器上不能并行执行。(每个处理器一个进程)

有关详细信息,请阅读此研究论文 并行编程的概念


1
“不可能在单个处理器上而是在多个处理器上并行执行”-当然,除了处理器内部存在并行执行路径外,例如,利用指令级并行性的系统(又名“超标量”架构,例如Intel处理器,因为奔腾,ARM Cortex和大多数其他高端处理器)以及单指令多数据,也称为数据并行体系结构(例如MMX / SSE / etc)。更不用说诸如数据流处理器之类的奇特的安排了。
Jules

3

并行处理是并行处理的子集。

并发处理描述了两个异步发生的任务,这意味着任务的执行顺序是不确定的。通过交织可执行指令,两个线程可以在同一处理器内核上同时运行。例如,线程1运行10毫秒,线程2运行10毫秒,等等。

并行处理是一种并行处理,其中同时执行多个指令集。这可能是多个系统共同解决分布式计算中的常见问题,或者是同一系统上的多个内核。


0

tdammer的声明已接近尾声,剩下的就是重点。他说:

“大胆地说,并发描述了一个问题(两件事需要一起发生),而并行描述了一个解决方案(两个处理器内核用于同时执行两件事”)

让我们来分析一下单词。

当前意味着此时此刻正在发生的,实际的,相关的。骗子是指反对,反对,不赞同。

平行是指在相同方向上没有交叉,而不会彼此阻碍。

因此,并发意味着要争夺相同的资源。并行性则没有。并行进程可能正在使用相同的资源,但不认为是问题,这不是问题。对于并发,这是一个要处理的问题。


“当前意味着此时此刻正在发生的,实际的,相关的。骗局意味着反对,反驳,不吻合。” -需要引用。我强烈怀疑这两种说法。尽管“当前”可以具有英语中提到的含义,但不是“并发”一词中使用的含义
绿巨人

1
我认为并发从拉丁语的翻译是“一起运行”。前缀“ con”通常意味着在一起,例如在阴谋(一起呼吸)结果(在一起或跟随)结论(接近)等方面。这是令人讨厌的语言,某些事物可能具有相反的含义,制裁是我最喜欢的例子。

@no comprende在这种情况下(并发),一起运行似乎确实更合适。由于没有顺应...在荷兰语中,并发是一个名词,表示竞争者。Courant很常见,到处都是。它也是报纸。现在正在活动的东西。“ Regenting courant”是一个正在运行的帐户。我觉得并发意味着冲突。争夺相同资源。在同一个空间中运行。也许是因为荷兰语的意思(竞争对手)。
马丁·马特

我想知道迪克斯特拉怎么说?

-1

显然,这些术语在不同的文化中使用不同。

我的理解如下:

并行是一种加快处理速度的方法。无论您是在单个内核,多个内核甚至在GPU上执行矩阵乘法,结果都是一样的(否则您的程序就坏了)。它不会向某些程序添加新功能,而只是提高速度。

尽管并发是您无法按顺序执行的事情。例如,在等待下一个请求的同时,为3个客户端提供3个不同的网页。(尽管您可以像以前那样通过交错在某种程度上模拟它。)请注意,并发程序的行为是不确定的。例如,目前尚不清楚,将首先完全服务3个客户中的哪个。您可以运行很多测试,并且每次完成请求的顺序都会得到不同的结果。运行时系统应保证a)将为所有客户提供服务,b)在合理的时间内。

通常,并行计算的工作马不了解也不关心并行性。虽然并发任务通常显式采用进程间或线程间通信,例如阻塞队列,同步和锁定机制。


-1

在我看来,从应用程序编程的角度来看,这两个概念之间没有区别,并且两个单词混淆起来也是令人困惑的。我认为线程交织是在不太可能使用多核的时代带来的,以模拟多核处理。为什么我们对这种过时的心态有一个词?

梅森·惠勒和企鹅给出了相同的答案。具有任务切换功能或多核功能的一个内核是并发的,严格来说,多核=并行。

我的观点是,这两个术语应合而为一,我努力避免说“并发”。我猜在OS编程级别上,区别很重要,但是从应用程序程序员的角度来看,这并不太重要。我已经编写了mapReduce,Spark,MPI,cuda,openCL和多线程c ++,而我从来不必停止思考该作业是使用交错线程还是使用多个内核。

例如,当我编写多线程c ++时,有时不确定要获得多少个内核,尽管有一些方法可以要求获得多少个内核,如此处所述https://stackoverflow.com/questions/2166425/如何结构化AC应用程序使用多核处理器。在spark中,我只是映射并减少操作,不知道jvm在硬件级别如何处理它们。我认为在GPU上每个线程都分配给它自己的简单处理器,但是无论何时出现问题,我总是同步我的线程。使用MPI,可以明确指定机器之间的通信,但是我们可以交错运行在单个内核上的多台机器上的功能,并通过适当的单线程功能组合结果。如果我们使用MPI来协调一堆单核机器,每台机器都具有多线程,该怎么办?有什么区别?我不会说。称其为“平行”并完成它。


2
这种区别在今天仍然有意义。您最多只能拥有硬件拥有的CPU内核数量的并行性,但是许多程序一次执行数百个并发计算,这要比硬件拥有的内核数量多得多。如果不了解这种区别,可能会导致程序员无法理解为什么并行化程序的运行速度比单线程版本(或线程数量少)慢。
Lie Ryan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.