并发编程和并行编程有什么区别?

mat*_*ekm 332 language-agnostic parallel-processing concurrency

并发编程和并行编程有什么区别?我问谷歌,但没有找到任何帮助我理解这种差异的东西.你能给我一个例子吗?

现在我发现了这个解释:http://www.linux-mag.com/id/7411 - 但"并发性是程序的属性"vs"并行执行是机器的属性"对我来说还不够 - 我还不能说什么是什么.

Jon*_*rop 388

并发编程考虑了看似重叠的操作,主要关注由于非确定性控制流而引起的复杂性.与并发程序相关的定量成本通常是吞吐量和延迟.并发程序通常是IO绑定但并非总是如此,例如并发垃圾收集器完全在CPU上.并发程序的教学示例是Web爬行程序.该程序启动对网页的请求,并在下载结果可用时同时接受响应,累积已经访问过的一组页面.控制流是不确定的,因为每次运行程序时,响应不一定以相同的顺序接收.这种特性使得调试并发程序变得非常困难.某些应用程序基本上是并发的,例如Web服务器必须同时处理客户端连接.Erlang可能是高度并发编程最有前途的语言.

并行编程涉及为提高吞吐量的特定目标而重叠的操作.通过使控制流确定性来避免并发编程的困难.通常,程序会生成并行运行的子任务集,而父任务仅在每个子任务完成后才会继续.这使得并行程序更容易调试.并行编程的难点在于粒度和通信等问题的性能优化.后者在多核的背景下仍然是一个问题,因为将数据从一个缓存传输到另一个缓存有相当大的成本.密集矩阵 - 矩阵乘法是并行编程的教学示例,可以使用Straasen'有效地求解 分而治之的算法并行地攻击子问题.Cilk可能是共享内存计算机(包括多核)上最有前途的高性能并行编程语言.

  • @BoppityBop只是因为我可以在一幅画中说出他在小说中所说的并不能使我的答案不那么正确.对于那些实际上不知道答案的人来说,更容易阅读.我想这是来到这里的重点.你可以用这篇文章所用的语言写一本书,但这对大多数读者来说绝对是胡言乱语,因为如果你已经知道jon所写的一半,你可能没有谷歌这个问题. (42认同)
  • *"并行编程的难点......如粒度和通信."*如果并行任务需要通信,是不是会使它们并发? (17认同)
  • 这张照片对我很有帮助,一个对这个话题很新的人,来自@JonHarrop的描述对我来说很有用,一个欣赏正确的人,即使是技术性的语言.这两个答案都有助于我更完整地理解.我们都赢了!(虽然我很欣赏并行执行和并行编程之间的区别) (17认同)
  • "如果并行任务需要通信,那么这不会使它们并发吗?" 哇,好问题!不一定,没有.超级计算机通常使用批量并行操作进行编程,然后进行全局数据重新分配和更多批量并行操作.所以存在并行性和通信性,但没有真正的并发性可言.在这种情况下,我更多地考虑多核并行性,其中通信意味着缓存复杂性,例如缓存一致性所需的通信.虽然这是并发的,但它也不是直接可见的. (12认同)
  • "Erlang可能是最有希望*即将推出的*语言......".有趣的选择,因为Erlang已经有30年的历史了,并且在1998年开源. (3认同)
  • @TorValamo:我在你的图表中没有看到非确定性控制流与吞吐量。 (2认同)

Tor*_*amo 297

如果你的程序正在使用线程(并发编程),它不一定会被执行(并行执行),因为它取决于机器是否可以处理多个线程.

这是一个可视化的例子.非线程机器上的线程:

        --  --  --
     /              \
>---- --  --  --  -- ---->>
Run Code Online (Sandbox Code Playgroud)

线程机器上的线程:

     ------
    /      \
>-------------->>
Run Code Online (Sandbox Code Playgroud)

破折号表示执行的代码.如您所见,它们分开并分别执行,但线程机器可以同时执行多个单独的部分.

  • 并行执行和并行编程不是一回事.Jon Harrop的答案是正确的.但似乎问题本身混淆了并行执行和并行编程. (33认同)
  • 并行执行线程的能力不仅取决于机器.例如,由于垃圾收集器的全局锁定,OCaml(和Python?)并发执行线程但不并行执行. (2认同)
  • 这个答案有利于可视化并发和并行执行之间的区别,但不适用于发布者关于 **programming** 的原始问题。 (2认同)

GKi*_*lin 141

https://joearms.github.io/published/2013-04-05-concurrent-and-parallel-programming.html

Concurrent =两个队列和一台咖啡机.

平行=两个队列和两台咖啡机.

  • 不正确和误导.Concurrent =允许*一个或多个*队列(非确定性组合).并行=拥有多个队列,使其中任何一个队列*比原始队列更短*如果不是空的(渐近效率). (8认同)
  • @GeoffreyAnderson不,不.例如,线程和进程在单个核心机器上并发执行. (3认同)

psp*_*spi 35

将原始问题解释为并行/并发计算而不是编程.

并发计算中,两个计算都彼此独立地前进.第二次计算不必等到第一次计算结束才能推进.然而,它没有说明如何实现这一目标的机制.在单核设置中,需要在线程之间挂起和交替(也称为抢占式多线程).

并行计算中,两个计算同时进行 - 即字面上同时进行.单CPU不可能实现这一点,而是需要多核设置.

暂停和轮流并行计算

根据:"Node.js中的并行与并发".

  • Image^顺序:并发在左边;平行线在右边。 (3认同)

moh*_*our 23

在处理器的视图中,可以通过该pic描述

在处理器的视图中,可以通过该pic描述

在处理器的视图中,可以通过该pic描述


小智 20

我相信并发编程是指多线程编程,它让你的程序运行多个线程,从硬件细节中脱颖而出.

并行编程是指专门设计程序算法以利用可用的并行执行.例如,您可以并行执行某些算法的两个分支,期望它比您第一次检查第一个分支然后第一个分支时更快(平均)得到结果.

  • 换句话说,并行执行两件事可以让他们以两倍的速度完成任务.同时执行两个操作可能仍然需要花费相同的时间来执行第一个操作,然后执行另一个操作,如果只有一个CPU时间切片来回运行一个第一个,然后是第二个,等等. (2认同)

lok*_*ath 13

我在一些博客中发现了这个内容.认为它是有用的和相关的.

并发和并行不是一回事.如果两个任务在时间上执行的顺序没有预先确定,则两个任务T1和T2是并发的,

T1可以执行并在T2之前完成,T2可以执行并在T1之前完成,T1和T2可以在同一时间(并行)同时执行,T1和T2可以交替执行,......如果两个并发线程由OS安排在一个单核非SMT非CMP处理器上运行,您可能会获得并发但不能并行.在多核,多处理器或分布式系统上可以实现并行化.

并发通常被称为程序的属性,并且是比并行性更通用的概念.

资料来源:https://blogs.oracle.com/yuanlin/entry/concurrency_vs_parallelism_concurrent_programming


Jer*_*fin 8

它们是两个短语,从(非常轻微)不同的观点来描述相同的事物.并行编程从硬件的角度描述了这种情况 - 至少有两个处理器(可能在一个物理包内)并行处理问题.并发编程从软件的角度更多地描述事物 - 两个或多个动作可能在完全相同的时间(并发)发生.

这里的问题是,当没有真正存在时,人们试图使用这两个短语来区分.现实情况是,他们试图绘制的分界线几十年来一直模糊不清,随着时间的推移变得越来越模糊.

他们试图讨论的事实是,曾几何时,大多数计算机只有一个CPU.当您在该单个CPU上执行多个进程(或线程)时,CPU实际上只是一次从其中一个线程执行一条指令.并发的出现是一种错觉 - CPU在不同线程执行指令之间切换到人类感知(任何小于100毫秒左右的时间看起来都是瞬间的),看起来它一下子做了很多事情.

与此形成鲜明对比的是具有多个CPU的计算机,或具有多个内核的CPU,因此机器在几乎同时执行来自多个线程和/或进程的指令; 执行一个代码的代码不能/不会对另一个代码执行产生影响.

现在的问题是:这种清晰的区别几乎从未存在过.计算机设计人员实际上相当聪明,所以他们很久以前就注意到(例如)当你需要从磁盘等I/O设备读取一些数据时,需要花费长时间(就CPU周期而言)完.他们没有在发生这种情况时让CPU空闲,而是找出了让一个进程/线程发出I/O请求的各种方法,并在I/O请求完成时让来自其他进程/线程的代码在CPU上执行.

因此,在多核CPU成为常态之前很久,我们就有多个线程并行运行.

这只是冰山一角.几十年前,计算机也开始提供另一种并行性.同样,作为相当聪明的人,计算机设计人员注意到在很多情况下,他们的指令不会相互影响,因此可以同时从同一个流执行多个指令.一个鲜为人知的早期例子是Control Data 6600.这是(在相当大的范围内)1964年推出时最快的计算机 - 并且大部分相同的基本架构至今仍在使用.它跟踪每条指令使用的资源,并有一组执行单元,只要它们所依赖的资源可用,就会执行指令,这与最新的Intel/AMD处理器的设计非常相似.

但是(正如商业广告所说)等待 - 这不是全部.还有另一个设计元素会进一步增加混乱.它被赋予了不同的名称(例如,"超线程","SMT","CMP"),但它们都指的是相同的基本思想:一个可以同时执行多个线程的CPU,使用一些资源的组合对于每个线程都是独立的,以及线程之间共享的一些资源.在典型情况下,这与上面概述的指令级并行性相结合.为此,我们有两组(或更多组)架构寄存器.然后我们有一组执行单元,一旦必要的资源可用就可以执行指令.这些通常很好地结合在一起,因为来自不同流的指令实际上从不依赖于相同的资源.

然后,当然,我们可以使用具有多个内核的现代系统.事情很明显,对吗?我们有N(大约在2到256左右,目前)单独的核心,它们都可以同时执行指令,所以我们有明确的实际并行性的情况 - 在一个进程/线程中执行指令没有'影响另一个人执行指令.

好吧,有点.即使在这里,我们也有一些独立的资源(寄存器,执行单元,至少一级缓存)和一些共享资源(通常至少是最低级别的缓存,绝对是内存控制器和内存带宽).

总结一下:人们喜欢在共享资源和独立资源之间进行对比的简单场景几乎从未在现实生活中发生过.在共享所有资源的情况下,我们最终会得到像MS-DOS这样的东西,我们一次只能运行一个程序,而我们必须先停止运行一个程序才能运行另一个程序.有了完全独立的资源,我们有N台计算机运行MS-DOS(甚至没有连接它们的网络),根本无法在它们之间共享任何东西(因为如果我们甚至可以共享一个文件,那么,这是一个共享资源,违反没有任何共享的基本前提).

每个有趣的案例都涉及独立资源和共享资源的某种组合.每一台合理的现代计算机(以及一些完全没有现代化的计算机)至少具有一些能够同时执行至少一些独立操作的能力,并且几乎比MS-DOS更复杂的任何计算机都至少利用了这一点.一定程度上.

人们喜欢绘制的"并发"和"并行"之间的良好,清晰的划分并不存在,而且几乎从来没有.人们喜欢将其归类为"并发"通常仍然涉及至少一种且通常更多不同类型的并行执行.他们喜欢将其归类为"并行"通常涉及共享资源和(例如)一个进程阻止另一个进程,同时使用在两者之间共享的资源.

试图在"平行"和"并发"之间划清界限的人们生活在一个从未真正存在的计算机幻想中.


小智 5

1.定义:

经典的任务安排可以是__CODE__,__CODE____CODE__

__CODE__ 分析表明,MUST BE executed one after the other已知序列中的任务被欺骗了OR it will not work.

即:很简单,我们可以忍受这个

__CODE__分析显示任务MUST BE executed at the same time OR it will not work.

  • 任何任务的失败 - 无论是在功能上还是在时间上 - 都将导致整个系统故障.
  • 所有任务必须具有共同的可靠时间感.

即:尽量避免这种情况,否则我们会在下午茶时间流泪.

__CODE__ 分析表明我们NEED NOT CARE.我们并非粗心大意,我们已经对它进行了分析并且无所谓; 我们可以因此执行任何使用任务的任何可用的设施在任何时间.

即:快乐的日子


通常,调度可用已知事件的变化,我称之为状态变化.


这不是{ Software | Programming } Feature一种Systems Design方法:

人们往往认为这是关于软件,但它实际上是一个systems design概念,预日期的计算机

软件系统的使用速度有点慢,很少有软件语言试图解决这个问题.

你可以 尝试寻找晶片的语言__CODE__,如果你有兴趣在一个很好的尝试.

(__CODE__具有许多主要创新(如果不是首屈一指)的功能,包括明确的语言支持__CODE____CODE__代码部分执行构造函数,其他语言主要在近年来可用的大规模并行处理器阵列的时代遭受重新发明轮毂InMOS Transputers使用超过35年前(!!!))


3. Systems Design需要注意的是:

简洁地说,systems design解决了以下问题:

动词 - 你在做什么.(操作算法)

的名词-你在它干嘛.(数据接口)

WHEN -启动,时间表,状态更改__CODE__,__CODE__,__CODE__

WHERE -一旦你知道事情发生,然后你可以说在那里他们可以发生,而不是之前.

为什么 - 这是一种方法吗?还有其他方法吗?有最好的方法吗?

.. 最后但并非最不重要 .. WHAT HAPPENS IF YOU DO NOT DO IT ?


4. PARALLELSERIAL方法的视觉示例:

最近 Parallel architectures于2014年在16-,64-,1024-并行RISC uP-s阵列上发布

true parallel history二十世纪后期 - 从20世纪90年代早期开始的Inmos Transputer CPU演示视频的一部分

祝好运

  • 这个答案比并发和并行主题更复杂. (10认同)
  • 我到处都看到了帽子 (8认同)

Jin*_*Heo 5

在编程中,并发性是独立执行进程的组合,而并行性是(可能相关的)计算的同时执行.
- Andrew Gerrand -

并发性是独立执行计算的组合.并发是一种构建软件的方法,特别是作为编写与现实世界良好交互的干净代码的一种方式.这不是平行主义.

并发不是并行性,尽管它可以实现并行性.如果您只有一个处理器,那么您的程序仍然可以并发,但它不能并行.另一方面,编写良好的并发程序可以在多处理器上并行高效运行.那个属性可能很重要......
- Rob Pike -

为了理解这种差异,我强烈建议看看这个Rob Pike(Golang创作者之一)的视频.并发不是并行性


sha*_*ent 5

并行编程在代码同时执行且每次执行独立于另一个时发生.因此,通常没有关于共享变量的关注,因为这不可能发生.

但是,并发编程包括由共享变量等的不同进程/线程执行的代码,因此在并发编程时我们必须建立某种规则来决定首先执行哪个进程/线程,我们想要这样做以便我们可以确定将是一致性,我们可以肯定地知道会发生什么.如果没有控制权并且所有线程同时计算并将事物存储在相同的变量上,我们怎么知道最终会发生什么?也许一个线程比另一个线程更快,可能其中一个线程甚至在其执行过程中停止,而另一个线程继续使用损坏的(尚未完全计算的)变量进行不同的计算,可能性是无穷无尽的.在这些情况下,我们通常使用并发编程而不是并行编程.


snr*_*snr 5

  • Concurrent programming一般意义上是指我们定义的任务可以按任何顺序发生的环境.一个任务可以在另一个任务之前或之后发生,并且一些或所有任务可以同时执行.

  • Parallel programming具体是指在不同处理器上同时执行并发任务.因此,所有并行编程都是并发的,但并非所有并发编程都是并行的.

资料来源:PThreads编程 - 更好的多处理POSIX标准,Buttlar,Farrell,Nichols