Model of computation
并行编程模型与计算模型密切相关。并行计算模型是一种抽象,用于分析计算过程的成本,但不一定需要实用,因为它可以在硬件和/或软件中有效地实现。相比之下,编程模型确实特别暗示了硬件和软件实现的实际考虑。[10]
计算模型可分为三类:顺序模型、功能模型和并发模型。
Sequential models
Sequential models include:
- Finite state machines
- Post machines (Post–Turing machines and tag machines).
- Pushdown automata
- Register machines
- Turing machines
- Decision tree model
Functional models
Functional models include:
Concurrent models
Concurrent models include:
- Actor model
- Cellular automaton
- Interaction nets
- Kahn process networks
- Logic gates and digital circuits
- Petri nets
- Synchronous Data Flow
在计算领域,并行编程模型是并行计算机体系结构的一种抽象概念,利用它可以方便地在程序中表达算法及其组成。一个编程模型的价值可根据其通用性来判断:在各种不同的体系结构下,一系列不同问题的表达效果如何;以及其性能:编译后的程序执行效率如何。并行编程模型的实现形式可以是从顺序语言中调用的库,也可以是对现有语言的扩展,还可以是一种全新的语言。
围绕特定编程模型达成共识非常重要,因为这将导致不同的并行计算机在构建时支持该模型,从而促进软件的可移植性。从这个意义上讲,编程模型被称为硬件和软件之间的桥梁。
Example parallel programming models
| Name | Class of interaction | Class of decomposition | Example implementations |
| Actor model | Asynchronous message passing(异步消息传递) | Task | D, Erlang, Scala, SALSA |
| Bulk synchronous parallel | Shared memory | Task | Apache Giraph, Apache Hama, BSPlib |
| Communicating sequential processes | Synchronous message passing(同步消息传递) | Task | Ada, Occam, VerilogCSP, Go |
| Circuits | Message passing(消息传递) | Task | Verilog, VHDL |
| Dataflow | Message passing | Task | Lustre, TensorFlow, Apache Flink |
| Functional | Message passing | Task | Concurrent Haskell, Concurrent ML |
| LogP machine | Synchronous message passing(同步消息传递) | Not specified | None |
| Parallel random access machine | Shared memory | Data | Cilk, CUDA, OpenMP, Threading Building Blocks, XMTC |
| SPMD PGAS | Partitioned global address space(分区的全局地址空间) | Data | Fortran 2008, Unified Parallel C, UPC++, SHMEM |
| Global-view Task parallelism | Partitioned global address space | Task | Chapel, X10 |
在某些并发计算系统中,并发组件之间的通信对程序员是隐藏的(例如,通过使用futures),而在其他系统中,则必须显式处理。显式通信可分为两类:
Shared memory communication
并发组件通过更改共享内存位置的内容进行通信(Java 和 C# 就是例子)。这种并发编程方式通常需要使用某种形式的锁定(如互斥、半隐或监视器)来协调线程之间的关系。能正确实现其中任何一种的程序都被称为线程安全程序。
Message passing communication
并发组件通过交换消息进行通信(以 MPI、Go、Scala、Erlang 和 occam 为例)。消息的交换可以异步进行,也可以使用同步的 "交会 "方式,在这种方式下,发送方会阻塞直到收到消息。异步消息传递可能是可靠的,也可能是不可靠的(有时称为 "发送和祈祷")。消息传递并发性往往比共享内存并发性更容易推理,通常被认为是一种更健壮的并发编程形式。[引述需要] 有各种各样的数学理论可用于理解和分析消息传递系统,包括角色模型和各种进程计算。消息传递可通过对称多进程有效实现,无论是否具有共享内存缓存一致性。
共享内存和消息传递并发具有不同的性能特征。通常情况下(尽管并非总是如此),在消息传递系统中,每个进程的内存开销和任务切换开销较低,但消息传递的开销要大于过程调用。这些差异往往被其他性能因素所掩盖。
实现
并发性在计算领域非常普遍,从单个芯片上的低级硬件到全球网络都存在并发性。下面举例说明。
在编程语言层面:
At the operating system level:
- Computer multitasking, including both cooperative multitasking and preemptive multitasking
- Time-sharing, which replaced sequential batch processing of jobs with concurrent use of a system
- Process
- Thread
在网络层面上,网络系统通常具有并发性,因为它们由独立的设备组成
支持并发编程的语言
并发编程语言是使用并发语言结构的编程语言。这些构造可能涉及多线程、分布式计算支持、消息传递、共享资源(包括共享内存)或期货和承诺。这类语言有时被称为面向并发的语言或面向并发的编程语言(COPL)。
目前,最常用的具有特定并发结构的编程语言是 Java 和 C#。这两种语言从根本上都使用共享内存并发模型,由监控器提供锁定(尽管消息传递模型可以并已经在底层共享内存模型之上实现)。在使用消息传递并发模型的语言中,Erlang 可能是目前业界使用最广泛的语言。
许多并发编程语言更多是作为研究语言(如 Pict)而不是作为生产语言开发的。不过,在过去 20 年中,Erlang、Limbo 和 occam 等语言曾在不同时期用于工业生产。使用或提供并发编程设施的语言不完全列表:
- Ada—general purpose, with native support for message passing and monitor based concurrency
- Alef—concurrent, with threads and message passing, for system programming in early versions of Plan 9 from Bell Labs
- Alice—extension to Standard ML, adds support for concurrency via futures
- Ateji PX—extension to Java with parallel primitives inspired from π-calculus
- Axum—domain specific, concurrent, based on actor model and .NET Common Language Runtime using a C-like syntax
- BMDFM—Binary Modular DataFlow Machine
- C++—std::thread
- Cω (C omega)—for research, extends C#, uses asynchronous communication
- C#—supports concurrent computing using lock, yield, also since version 5.0 async and await keywords introduced
- Clojure—modern, functional dialect of Lisp on the Java platform
- Concurrent Clean—functional programming, similar to Haskell
- Concurrent Collections (CnC)—Achieves implicit parallelism independent of memory model by explicitly defining flow of data and control
- Concurrent Haskell—lazy, pure functional language operating concurrent processes on shared memory
- Concurrent ML—concurrent extension of Standard ML
- Concurrent Pascal—by Per Brinch Hansen
- Curry
- D—multi-paradigm system programming language with explicit support for concurrent programming (actor model)
- E—uses promises to preclude deadlocks
- ECMAScript—uses promises for asynchronous operations
- Eiffel—through its SCOOP mechanism based on the concepts of Design by Contract
- Elixir—dynamic and functional meta-programming aware language running on the Erlang VM.
- Erlang—uses asynchronous message passing with nothing shared
- FAUST—real-time functional, for signal processing, compiler provides automatic parallelization via OpenMP or a specific work-stealing scheduler
- Fortran—coarrays and do concurrent are part of Fortran 2008 standard
- Go—for system programming, with a concurrent programming model based on CSP
- Haskell—concurrent, and parallel functional programming language
- Hume—functional, concurrent, for bounded space and time environments where automata processes are described by synchronous channels patterns and message passing
- Io—actor-based concurrency
- Janus—features distinct askers and tellers to logical variables, bag channels; is purely declarative
- Java—thread class or Runnable interface
- Julia—"concurrent programming primitives: Tasks, async-wait, Channels."
- JavaScript—via web workers, in a browser environment, promises, and callbacks.
- JoCaml—concurrent and distributed channel based, extension of OCaml, implements the join-calculus of processes
- Join Java—concurrent, based on Java language
- Joule—dataflow-based, communicates by message passing
- Joyce—concurrent, teaching, built on Concurrent Pascal with features from CSP by Per Brinch Hansen
- LabVIEW—graphical, dataflow, functions are nodes in a graph, data is wires between the nodes; includes object-oriented language
- Limbo—relative of Alef, for system programming in Inferno (operating system)
- Locomotive BASIC—Amstrad variant of BASIC contains EVERY and AFTER commands for concurrent subroutines
- MultiLisp—Scheme variant extended to support parallelism
- Modula-2—for system programming, by N. Wirth as a successor to Pascal with native support for coroutines
- Modula-3—modern member of Algol family with extensive support for threads, mutexes, condition variables
- Newsqueak—for research, with channels as first-class values; predecessor of Alef
- occam—influenced heavily by communicating sequential processes (CSP)
- occam-π—a modern variant of occam, which incorporates ideas from Milner's π-calculus
- Orc—heavily concurrent, nondeterministic, based on Kleene algebra
- Oz-Mozart—multiparadigm, supports shared-state and message-passing concurrency, and futures
- ParaSail—object-oriented, parallel, free of pointers, race conditions
- Pict—essentially an executable implementation of Milner's π-calculus
- Raku includes classes for threads, promises and channels by default
- Python — uses thread-based parallelism and process-based parallelism
- Reia—uses asynchronous message passing between shared-nothing objects
- Red/System—for system programming, based on Rebol
- Rust—for system programming, using message-passing with move semantics, shared immutable memory, and shared mutable memory.
- Scala—general purpose, designed to express common programming patterns in a concise, elegant, and type-safe way
- SequenceL—general purpose functional, main design objectives are ease of programming, code clarity-readability, and automatic parallelization for performance on multicore hardware, and provably free of race conditions
- SR—for research
- SuperPascal—concurrent, for teaching, built on Concurrent Pascal and Joyce by Per Brinch Hansen
- Swift—built-in support for writing asynchronous and parallel code in a structured way
- Unicon—for research
- TNSDL—for developing telecommunication exchanges, uses asynchronous message passing
- VHSIC Hardware Description Language (VHDL)—IEEE STD-1076
- XC—concurrency-extended subset of C language developed by XMOS, based on communicating sequential processes, built-in constructs for programmable I/O
许多其他语言都以库的形式提供并发性支持,支持程度与上述语言大致相当。