diff --git a/reference/parallel/book.xml b/reference/parallel/book.xml index 6da4c01a21..7842cae905 100644 --- a/reference/parallel/book.xml +++ b/reference/parallel/book.xml @@ -2,8 +2,8 @@ - Parallel - Parallel + parallel + parallel &reftitle.intro; @@ -25,6 +25,13 @@ A parallel\Runtime has a FIFO schedule, tasks will be executed in the order that they are scheduled. + + Functional API + + parallel implements a functional, higher level API on top of parallel\Runtime that provides a single function entry point to executing parallel code + with automatic scheduling: parallel\run. + + Task @@ -80,9 +87,17 @@ describing the operations that have occured. + + &reftitle.seealso; + + + + &reference.parallel.setup; + &reference.parallel.philosophy; + &reference.parallel.functional; &reference.parallel.parallel.runtime; &reference.parallel.parallel.future; &reference.parallel.parallel.channel; diff --git a/reference/parallel/functional.xml b/reference/parallel/functional.xml new file mode 100644 index 0000000000..19b64cbaa9 --- /dev/null +++ b/reference/parallel/functional.xml @@ -0,0 +1,49 @@ + + + + + Functional API + + + The parallel\Runtime API provides a great degree of control to the power PHP programmer, and those intimately familiar with writing applications that use + parallel concurrency. + + + The functional API provides less control in exchange for the ability to make decisions for the programmer: + + + all executing runtimes are bootstrapped identically + + + scheduling is determined by the API, not the programmer + + + parallel\run provides the guarantee that the task will begin to execute in parallel as soon as allowed by hardware and operating system constraints, without + needlessly creating runtimes. For most applications the functional API should be preferred. + + + + &reference.parallel.functions.parallel.bootstrap; + &reference.parallel.functions.parallel.run; + + + diff --git a/reference/parallel/functions/parallel.bootstrap.xml b/reference/parallel/functions/parallel.bootstrap.xml new file mode 100644 index 0000000000..c7714802c7 --- /dev/null +++ b/reference/parallel/functions/parallel.bootstrap.xml @@ -0,0 +1,62 @@ + + + + + + parallel\bootstrap + Bootstrapping + + + + &reftitle.description; + + voidparallel\bootstrap + stringfile + + + Shall use the provided file to bootstrap all runtimes created for automatic scheduling via parallel\run. + + + + + Exceptions + + + Shall throw \parallel\Runtime\Error\Bootstrap if previously called for this process. + + + + + Shall throw \parallel\Runtime\Error\Bootstrap if called after parallel\run. + + + + + + &reftitle.seealso; + + + + + + + diff --git a/reference/parallel/functions/parallel.run.xml b/reference/parallel/functions/parallel.run.xml new file mode 100644 index 0000000000..9465d264b7 --- /dev/null +++ b/reference/parallel/functions/parallel.run.xml @@ -0,0 +1,77 @@ + + + + + + parallel\run + Execution + + + + &reftitle.description; + + ?Futureparallel\run + Closuretask + + + Shall schedule task for execution in parallel. + + + ?Futureparallel\run + Closuretask + arrayargv + + + Shall schedule task for execution in parallel, passing argv at execution time. + + + + + Automatic Scheduling + + If a \parallel\Runtime internally created and cached by a previous call to parallel\run is idle, + it will be used to execute the task. If no \parallel\Runtime is idle parallel will create and cache a + \parallel\Runtime. + + + + \parallel\Runtime objects created by the programmer are not used for automatic scheduling. + + + + + + + + + + + + + &reftitle.seealso; + + + + + + + diff --git a/reference/parallel/parallel/runtime/run.xml b/reference/parallel/parallel/runtime/run.xml index f18c15003a..5dc1d7025c 100644 --- a/reference/parallel/parallel/runtime/run.xml +++ b/reference/parallel/parallel/runtime/run.xml @@ -4,7 +4,7 @@ parallel\Runtime::run - Parallel Execution + Execution @@ -55,7 +55,7 @@ Closures scheduled for parallel execution must not: accept or return by reference - accept or return objects (that are not closures) + accept or return internal objects (see notes) execute a limited set of instructions @@ -86,8 +86,8 @@ Arguments must not: contain references - contain objects (that are not closures) contain resources + contain internal objects (see notes) @@ -97,6 +97,29 @@ + + Internal Objects Notes + + Internal objects generally use a custom structure which cannot be copied by value safely, PHP currently lacks the mechanics to do this (without serialization) + and so only objects that do not use a custom structure may be shared. + + + Some internal objects do not use a custom structure, for example parallel\Events\Event and so may be shared. + + + Closures are a special kind of internal object and support being copied by value, and so may be shared. + + + Channels are central to writing parallel code and support concurrent access and execution by necessity, and so may be shared. + + + + A user class that extends an internal class may use a custom structure as defined by the internal class, in which case they cannot be copied by value safely, + and so may not be shared. + + + + &reftitle.returnvalues; diff --git a/reference/parallel/philosophy.xml b/reference/parallel/philosophy.xml new file mode 100644 index 0000000000..b2e0f4659c --- /dev/null +++ b/reference/parallel/philosophy.xml @@ -0,0 +1,77 @@ + + + + + Philosophy + + This section contains philosohpies important to writing parallel code and some details about the internal implementation of parallel. + + + Do not communicate by sharing memory; instead, share memory by communicating. + + This philosophy which is embraced by parallel has its origins in Go, one of the most widely admired if not used platforms for writing parallel code at the moment. + Go programmers have to work hard to live up to this ideal: PHP and parallel do all the hard work for the programmer, and by default. + + + In conventional threading models found in other languages, generally threads are communicating with one another through nothing more than by virtue of the fact that + they operate in the same address space. + The programmer must deploy mutual exclusion, condition variables, and other low level threading or synchronization primitives in order to ensure proper communication + of state and consistency. + + + When the conventional model is inversed, it means that threads only share memory as a result of communication (a variable is passed over a Channel for example). + + + When parallel passes a variable from one thread to another by any means - Task arguments, return via Future, and Channels - it is passed by value. + In all but the case of unbuffered channels, the variable is also buffered so that it may not change (or be destroyed) before it is used in whichever thread the variable + is being passed to. An unbuffered read over a channel is the only instance in which a thread directly reads memory allocated by another thread, it can do so safely because + the thread that owns the memory is waiting for the read to complete before it can continue to manipulate it, and the thread that does not own the memory reads by value. When + both threads continue, they are no longer sharing memory. + + + This makes writing and reasoning about parallel code much easier than the conventional model of threading. It means the programmer does not need to consider that threads + may be manipulating data concurrently, because that is not possible. + + + This also makes PHP the perfect platform for implementing a parallel concurrency API based on CSP (message passing over channels), because PHP itself is shared nothing - + PHP threads operate in their own virtual address space by default, and so may only share memory by communicating. + + + + Data should have a definitive single owner + + When approaching the CSP model for the first time, a programmer versed in the traditional model of threading may find themselves looking for concurrent data structures, + because that is what they are used too: they pass around shared objects for manipulation. + + + When it comes to the CSP model, there is no need for data structures to be shared by many tasks, and indeed, it is simpler if they are not. The data should be owned + by a single task, changes to (or operations on) that data structure should be communicated over channels and performed by the owner of the data, the success, failure, + or result (state) of the change (or operation) being communicated back. + + + Once again the share nothing nature of PHP and copy by value nature of parallel helps the programmer to achieve this goal, no data will be shared by accident, + only ever as a result of communication. + + + + + diff --git a/reference/parallel/setup.xml b/reference/parallel/setup.xml index bb25cde4ab..fe065f4794 100644 --- a/reference/parallel/setup.xml +++ b/reference/parallel/setup.xml @@ -2,9 +2,9 @@ - &reftitle.setup; + Installation -
+ &reftitle.required; parallel requires a build of PHP with ZTS (Zend Thread Safety) enabled ( --enable-maintainer-zts or --enable-zts on Windows ) @@ -17,9 +17,9 @@ parallel should build anywhere there is a working Posix Threads header (pthread.h) and ZTS build of PHP, including Windows (using the pthread-w32 project from redhat). -
+ -
+ &reftitle.install; parallel releases are hosted by PECL and the source code by @@ -35,7 +35,7 @@ Windows users need to take the additional step of adding pthreadVC2.dll (distributed with Windows releases) to their PATH. -
+
diff --git a/reference/parallel/versions.xml b/reference/parallel/versions.xml index f23d23e7a9..9869ae7181 100644 --- a/reference/parallel/versions.xml +++ b/reference/parallel/versions.xml @@ -7,6 +7,9 @@ + + +