From 13322f5fc082bd831415766a11447a86bad5495a Mon Sep 17 00:00:00 2001 From: Jatin Arora Date: Tue, 7 Mar 2023 10:01:20 -0500 Subject: [PATCH 01/10] documentation for artifact --- README.md | 139 +++++++----------------------------------------------- 1 file changed, 17 insertions(+), 122 deletions(-) diff --git a/README.md b/README.md index 8d6d955aa..7e02e3ea6 100644 --- a/README.md +++ b/README.md @@ -1,82 +1,29 @@ # MPL -MaPLe (MPL) is an extension of the [MLton](http://mlton.org) -compiler for Standard ML which implements support for -nested (fork-join) parallelism. MPL generates executables with -excellent multicore performance, utilizing a novel approach to -memory management based on the theory of disentanglement +MaPLe (MPL) is a compiler for standard ML that implements +support for nested (fork-join) parallelism. MPL generates executables with +excellent multicore performance because it utilizes the theory of disentanglement +to manage memory of parallel programs. [[1](#rmab16),[2](#gwraf18),[3](#wyfa20),[4](#awa21),[5](#waa22)]. +It builds on the [MLton](http://mlton.org) compiler. -MPL is research software and is being actively developed. +Roughly speaking, the disentanglement property states that an object allocated +by a thread may not be shared with a concurrently executing thread. +MPL exploits disentanglement at the granularity of memory objects. Specifically, +it distinguishes between disentangled and entangled objects and handles disentangled objects very efficiently, +while incurring modest overhead for entangled objects, which are rare. -If you are you interested in using MPL, consider checking -out the [tutorial](https://github.com/MPLLang/mpl-tutorial). -You might also be interested in exploring -[`mpllib`](https://github.com/MPLLang/mpllib) -(a library for MPL) and the -[Parallel ML benchmark suite](https://github.com/MPLLang/parallel-ml-bench). - -## Docker - -Try out MPL with Docker: -``` -$ docker pull shwestrick/mpl -$ docker run -it shwestrick/mpl /bin/bash -...# examples/bin/primes @mpl procs 4 -- -``` - -If you want to try out MPL by writing and compiling your own code, we recommend -mounting a local directory inside the container. For example, here's how you -can use MPL to compile and run your own `main.mlb` in the current directory. -(To mount some other directory, replace `$(pwd -P)` with a different path.) -``` -$ ls -main.mlb -$ docker run -it -v $(pwd -P):/root/mycode shwestrick/mpl /bin/bash -...# cd /root/mycode -...# mpl main.mlb -...# ./main @mpl procs 4 -- -``` - - -## Build and Install (from source) - -### Requirements - -MPL has only been tested on Linux with x86-64. The following software is -required. - * [GCC](http://gcc.gnu.org) - * [GMP](http://gmplib.org) (GNU Multiple Precision arithmetic library) - * [GNU Make](http://savannah.gnu.org/projects/make), [GNU Bash](http://www.gnu.org/software/bash/) - * binutils (`ar`, `ranlib`, `strip`, ...) - * miscellaneous Unix utilities (`diff`, `find`, `grep`, `gzip`, `patch`, `sed`, `tar`, `xargs`, ...) - * Standard ML compiler and tools: - - Recommended: [MLton](http://mlton.org) (`mlton`, `mllex`, and `mlyacc`). Pre-built binary packages for MLton can be installed via an OS package manager or (for select platforms) obtained from http://mlton.org. - - Supported but not recommended: [SML/NJ](http://www.smlnj.org) (`sml`, `ml-lex`, `ml-yacc`). - -### Instructions - -The following builds the compiler at `build/bin/mpl`. -``` -$ make all -``` - -After building, MPL can then be installed to `/usr/local`: -``` -$ make install -``` -or to a custom directory with the `PREFIX` option: -``` -$ make PREFIX=/opt/mpl install -``` +We note, for the artifact reviewers, that MPL did not support entanglement +prior to our work. We do not elaborate on the differences between MPL and MPL* here +and instead present the language. The differences between MPL and MPL* are written in the paper. +Here we use MPL to mean MPL*. ## Parallel and Concurrent Extensions MPL extends SML with a number of primitives for parallelism and concurrency. -Take a look at `examples/` to see these primitives in action. +Take a look at `examples/` to see these primitives in action and run MPL +programs. -**Note**: Before writing any of your own code, make sure to read the section -"Disentanglement" below. ### The `ForkJoin` Structure ``` @@ -198,52 +145,7 @@ argument `bar` using 4 pinned processors. $ foo @mpl procs 4 set-affinity -- bar ``` -## Disentanglement - -Currently, MPL only supports programs that are **disentangled**, which -(roughly speaking) is the property that concurrent threads remain oblivious -to each other's allocations [[3](#wyfa20)]. - -Here are a number of different ways to guarantee that your code is -disentangled. -- (Option 1) Use only purely functional data (no `ref`s or `array`s). This is -the simplest but most restrictive approach. -- (Option 2) If using mutable data, use only non-pointer data. MPL guarantees -that simple types (`int`, `word`, `char`, `real`, etc.) are never -indirected through a -pointer, so for example it is safe to use `int array`. Other types such as -`int list array` and `int array array` should be avoided. This approach -is very easy to check and is surprisingly general. Data races are fine! -- (Option 3) Make sure that your program is race-free. This can be -tricky to check but allows you to use any type of data. Many of our example -programs are race-free. - -## Entanglement Detection - -Whenever a thread acquires a reference -to an object allocated concurrently by some other thread, then we say that -the two threads are **entangled**. This is a violation of disentanglement, -which MPL currently does not allow. - -MPL has a built-in dynamic entanglement detector which is enabled by default. -The entanglement detector monitors individual reads and writes during execution; -if entanglement is found, the program will terminate with an error message. - -The entanglement detector is both "sound" and "complete": there are neither -false negatives nor false positives. In other words, the detector always raises -an alarm when entanglement occurs, and never raises an alarm otherwise. Note -however that entanglement (and therefore also entanglement detection) can -be execution-dependent: if your program is non-deterministic (e.g. racy), -then entanglement may or may not occur depending on the outcome of a race -condition. Similarly, entanglement could be input-dependent. - -Entanglement detection is highly optimized, and typically has negligible -overhead (see [[5](#waa22)]). It can be disabled at compile-time by passing -`-detect-entanglement false`; however, we recommend against doing so. MPL -relies on entanglement detection to ensure memory safety. We recommend leaving -entanglement detection enabled at all times. - -## Bugs and Known Issues +## Known Issues ### Basis Library In general, the basis library has not yet been thoroughly scrubbed, and many @@ -253,13 +155,6 @@ Some known issues: * `Int.toString` is racy when called in parallel. * `Real.fromString` may throw an error when called in parallel. -### Garbage Collection -* ([#115](https://github.com/MPLLang/mpl/issues/115)) The GC is currently -disabled at the "top level" (outside any calls to `ForkJoin.par`). -For highly parallel programs, this has generally not been a problem so far, -but it can cause a memory explosion for programs that are mostly (or entirely) -sequential. - ## Unsupported MLton Features Many [MLton-specific features](http://mlton.org/MLtonStructure) are unsupported, including (but not limited to): From 275f4878668613796d6db23f096aa7c637d74076 Mon Sep 17 00:00:00 2001 From: Jatin Arora Date: Tue, 7 Mar 2023 10:10:05 -0500 Subject: [PATCH 02/10] update readme --- README.md | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 7e02e3ea6..8777ea205 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,21 @@ # MPL -MaPLe (MPL) is a compiler for standard ML that implements -support for nested (fork-join) parallelism. MPL generates executables with +MPL* is a compiler for standard ML that implements +support for nested (fork-join) parallelism. MPL* generates executables with excellent multicore performance because it utilizes the theory of disentanglement to manage memory of parallel programs. [[1](#rmab16),[2](#gwraf18),[3](#wyfa20),[4](#awa21),[5](#waa22)]. -It builds on the [MLton](http://mlton.org) compiler. +It builds on the [MPL](https://github.com/MPLLang/mpl) compiler. Roughly speaking, the disentanglement property states that an object allocated by a thread may not be shared with a concurrently executing thread. -MPL exploits disentanglement at the granularity of memory objects. Specifically, +MPL* exploits disentanglement at the granularity of memory objects. Specifically, it distinguishes between disentangled and entangled objects and handles disentangled objects very efficiently, while incurring modest overhead for entangled objects, which are rare. -We note, for the artifact reviewers, that MPL did not support entanglement -prior to our work. We do not elaborate on the differences between MPL and MPL* here -and instead present the language. The differences between MPL and MPL* are written in the paper. -Here we use MPL to mean MPL*. +We note, for the artifact reviewers, that MPL does not support entanglement but MPL* (the language presented in the paper) does. We are in the process of merging MPL* and MPL. In the meantime, we have two separate branches within the same [repo](https://github.com/MPLLang/mpl). MPL is at the master branch and MPL* is at pldi23-artifact. In this tour of MPL*, we call it MPL +because the difference between them is not important. + ## Parallel and Concurrent Extensions @@ -110,8 +109,6 @@ by default. * `-debug true -debug-runtime true -keep g` For debugging, keeps the generated C files and uses the debug version of the runtime (with assertions enabled). The resulting executable is somewhat peruse-able with tools like `gdb`. -* `-detect-entanglement true` enables the dynamic entanglement detector. -See below for more information. For example: ``` From 8b7916a1635c25f78e8872dc5723919ab64628e5 Mon Sep 17 00:00:00 2001 From: Jatin Arora Date: Tue, 7 Mar 2023 10:12:16 -0500 Subject: [PATCH 03/10] ex --- examples/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/README.md b/examples/README.md index 636c4d66d..1777bc1df 100644 --- a/examples/README.md +++ b/examples/README.md @@ -5,7 +5,7 @@ Each example program has a corresponding subdirectory in `src/`. The `lib/` directory contains common functions used across all examples. To build everything, run `make` or `make -j`. Compiled programs are -put into a `bin/`. +put into a `bin/`. You can also build programs one at a time as shown below. ## Fibonacci From 29b201e3ba127f064fc164c44698b0354f30d8c7 Mon Sep 17 00:00:00 2001 From: Jatin Arora Date: Tue, 7 Mar 2023 14:07:05 -0500 Subject: [PATCH 04/10] escape * --- README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8777ea205..b6295f5fa 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # MPL -MPL* is a compiler for standard ML that implements -support for nested (fork-join) parallelism. MPL* generates executables with +MPL-EM (MPL\*) is a compiler for standard ML that implements +support for nested (fork-join) parallelism. MPL-EM generates executables with excellent multicore performance because it utilizes the theory of disentanglement to manage memory of parallel programs. [[1](#rmab16),[2](#gwraf18),[3](#wyfa20),[4](#awa21),[5](#waa22)]. @@ -9,13 +9,11 @@ It builds on the [MPL](https://github.com/MPLLang/mpl) compiler. Roughly speaking, the disentanglement property states that an object allocated by a thread may not be shared with a concurrently executing thread. -MPL* exploits disentanglement at the granularity of memory objects. Specifically, +MPL-EM exploits disentanglement at the granularity of memory objects. Specifically, it distinguishes between disentangled and entangled objects and handles disentangled objects very efficiently, while incurring modest overhead for entangled objects, which are rare. -We note, for the artifact reviewers, that MPL does not support entanglement but MPL* (the language presented in the paper) does. We are in the process of merging MPL* and MPL. In the meantime, we have two separate branches within the same [repo](https://github.com/MPLLang/mpl). MPL is at the master branch and MPL* is at pldi23-artifact. In this tour of MPL*, we call it MPL -because the difference between them is not important. - +We note, for the artifact reviewers, that MPL does not support entanglement but MPL-EM (the language presented in the paper) does. We are in the process of merging MPL-EM and MPL. In the meantime, we have two separate branches within the same [repo](https://github.com/MPLLang/mpl). MPL is at the master branch and MPL-EM is at pldi23-artifact. ## Parallel and Concurrent Extensions From f2a16bd2cf557b1eb878f8b4675d959775ba9cd5 Mon Sep 17 00:00:00 2001 From: Jatin Arora Date: Tue, 7 Mar 2023 14:11:02 -0500 Subject: [PATCH 05/10] readme --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b6295f5fa..bffc375ce 100644 --- a/README.md +++ b/README.md @@ -13,13 +13,14 @@ MPL-EM exploits disentanglement at the granularity of memory objects. Specifical it distinguishes between disentangled and entangled objects and handles disentangled objects very efficiently, while incurring modest overhead for entangled objects, which are rare. + We note, for the artifact reviewers, that MPL does not support entanglement but MPL-EM (the language presented in the paper) does. We are in the process of merging MPL-EM and MPL. In the meantime, we have two separate branches within the same [repo](https://github.com/MPLLang/mpl). MPL is at the master branch and MPL-EM is at pldi23-artifact. ## Parallel and Concurrent Extensions MPL extends SML with a number of primitives for parallelism and concurrency. -Take a look at `examples/` to see these primitives in action and run MPL -programs. +To directly run some examples, +please read `examples/README.md` which provides instructions to run programs. ### The `ForkJoin` Structure From 7209b342e04feebca0995db5354f75c5ba35db30 Mon Sep 17 00:00:00 2001 From: Jatin Arora Date: Mon, 27 Mar 2023 15:18:21 -0400 Subject: [PATCH 06/10] some documentation comments --- runtime/gc/assign.c | 14 ++++++++++++++ runtime/gc/decheck.c | 9 ++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/runtime/gc/assign.c b/runtime/gc/assign.c index 1d5560a59..3c26682b5 100644 --- a/runtime/gc/assign.c +++ b/runtime/gc/assign.c @@ -8,6 +8,8 @@ */ #ifdef DETECT_ENTANGLEMENT +// read barrier for mutable objects +// the argument dst points to object src objptr Assignable_decheckObjptr(objptr dst, objptr src) { GC_state s = pthread_getspecific(gcstate_key); @@ -16,16 +18,25 @@ objptr Assignable_decheckObjptr(objptr dst, objptr src) pointer dstp = objptrToPointer(dst, NULL); HM_HierarchicalHeap dstHH = HM_getLevelHead(HM_getChunkOf(dstp)); + + /* if src is an unboxed value, or if it is scheduler data (depth 0), + * or dst is not in the frontier, + * then no entanglement checking required.*/ if (!isObjptr(src) || HM_HH_getDepth(dstHH) == 0 || !ES_contains(NULL, dst)) { return src; } // HM_EBR_leaveQuiescentState(s); + if (!decheck(s, src)) { assert (isMutable(s, dstp)); s->cumulativeStatistics->numEntanglements++; + /* the src object is entangled and its entanglement region may be pinned* + * the function manage_entangled (decheck.c: 435) is called pin_region in the PLDI paper + * Efficient parallel programming with effects.*/ + // the returned object new_src will differ from src if src has been relocated by garbage collection new_src = manage_entangled(s, src, getThreadCurrent(s)->decheckState); assert (isPinned(new_src)); } @@ -34,6 +45,8 @@ objptr Assignable_decheckObjptr(objptr dst, objptr src) return new_src; } + +// read barrier for mutable arrays objptr Assignable_readBarrier( GC_state s, objptr obj, @@ -95,6 +108,7 @@ static inline bool decheck_opt_fast (GC_state s, pointer p) { } +/*write barrier for updates*/ void Assignable_writeBarrier( GC_state s, objptr dst, diff --git a/runtime/gc/decheck.c b/runtime/gc/decheck.c index 14556e204..06c6cc360 100644 --- a/runtime/gc/decheck.c +++ b/runtime/gc/decheck.c @@ -320,6 +320,8 @@ bool decheckIsOrdered(GC_thread thread, decheck_tid_t t1) { #ifdef DETECT_ENTANGLEMENT #if ASSERT +// traverse the entanglement region and check all pinning and suspect invariants +// this function is super slow, don't call unless debugging. void traverseAndCheck( GC_state s, __attribute__((unused)) objptr *opp, @@ -465,6 +467,7 @@ objptr manage_entangled( current_pt != PIN_ANY || current_ud > unpinDepth; + /* skip entanglement management on scheduler objects (depth = 0)*/ if (current_pt != PIN_NONE && current_ud == 0) { return ptr; @@ -478,9 +481,14 @@ objptr manage_entangled( .unpinDepth = newUnpinDepth, .firstCall = !(current_pt == PIN_DOWN && current_ud == 1) }; + // this procedure loops and pins the entanglement region of ptr make_entangled(s, &ptr, ptr, (void*) &mea); } else { + /* the object is already pinned and marked entangled. + * It may not be marked as an entangled suspect because another thread maybe slow. + * Just ensure that if mutable, the object is a suspect (named entanglement candidates in the paper). + * see entanglement-supects.c */ if (isMutableH(s, header) && !ES_contains(NULL, ptr)) { HM_HierarchicalHeap lcaHeap = HM_HH_getHeapAtDepth(s, getThreadCurrent(s), unpinDepth); ES_add(s, HM_HH_getSuspects(lcaHeap), ptr); @@ -489,7 +497,6 @@ objptr manage_entangled( traverseAndCheck(s, &ptr, ptr, NULL); } - traverseAndCheck(s, &ptr, ptr, NULL); return ptr; // GC_header header = getRacyHeader(objptrToPointer(ptr, NULL)); From b9c5578c9e1bdeb92f251cd52f6d116ffd2b6ea3 Mon Sep 17 00:00:00 2001 From: Jatin Arora Date: Mon, 27 Mar 2023 16:23:13 -0400 Subject: [PATCH 07/10] updates --- release-notes.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 release-notes.md diff --git a/release-notes.md b/release-notes.md new file mode 100644 index 000000000..a9873fedc --- /dev/null +++ b/release-notes.md @@ -0,0 +1,19 @@ +With this version, +we lift the disentanglement restriction from MPL +and extend it to support all fork-join programs, no holds barred. + +MPL supports entangled programs by treating entanglement as an object-level property: +it distinguishes entangled objects from disentangled objects and manages them in-place, +without moving them. + +MPL dynamically distinguishes entangled objects and disentangled objects. +It does so with the help of the read barrier (see `runtime/gc/assign.c`), which +intercepts mutable reads and checks if they create entanglement. +If the read is entangled, the barrier pins the `entanglement region` of the entangled object, +instructing the collector not to move any object of the region +(performed by the function `manage_entangled`, see `runtime/gc/decheck.c`). +The write barrier accounts for inter-heap pointers created as a result of mutable updates by adding +them to the remembered set of the target heaps (see `Assignable_writeBarrier` in `runtime/gc/assign.c`). +The collection algorithm is a hybrid algorithm, which keeps the pinned entangled objects in place +and relocates disentangled objects to compact them (see function `markAndAdd` in `hierarchical-heap-collection.c`). + From ef10b0b3413eebc3a1f87f9b8dfd2817910d9c3b Mon Sep 17 00:00:00 2001 From: Jatin Arora Date: Mon, 27 Mar 2023 16:24:30 -0400 Subject: [PATCH 08/10] ed --- release-notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release-notes.md b/release-notes.md index a9873fedc..a854a4aa8 100644 --- a/release-notes.md +++ b/release-notes.md @@ -15,5 +15,5 @@ instructing the collector not to move any object of the region The write barrier accounts for inter-heap pointers created as a result of mutable updates by adding them to the remembered set of the target heaps (see `Assignable_writeBarrier` in `runtime/gc/assign.c`). The collection algorithm is a hybrid algorithm, which keeps the pinned entangled objects in place -and relocates disentangled objects to compact them (see function `markAndAdd` in `hierarchical-heap-collection.c`). +and relocates disentangled objects to compact them (see function `markAndAdd` and `HM_HHC_collectLocal` in `hierarchical-heap-collection.c`). From 2d47e56adddf7169c04c33ff8a579c3daa57cf1d Mon Sep 17 00:00:00 2001 From: Jatin Arora Date: Fri, 7 Apr 2023 09:40:41 -0400 Subject: [PATCH 09/10] build instructions --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/README.md b/README.md index bffc375ce..7cd285422 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,38 @@ while incurring modest overhead for entangled objects, which are rare. We note, for the artifact reviewers, that MPL does not support entanglement but MPL-EM (the language presented in the paper) does. We are in the process of merging MPL-EM and MPL. In the meantime, we have two separate branches within the same [repo](https://github.com/MPLLang/mpl). MPL is at the master branch and MPL-EM is at pldi23-artifact. + +## Build and Install (from source) + +### Requirements + +MPL has only been tested on Linux with x86-64. The following software is +required. + * [GCC](http://gcc.gnu.org) + * [GMP](http://gmplib.org) (GNU Multiple Precision arithmetic library) + * [GNU Make](http://savannah.gnu.org/projects/make), [GNU Bash](http://www.gnu.org/software/bash/) + * binutils (`ar`, `ranlib`, `strip`, ...) + * Standard ML compiler and tools: + - Recommended: [MLton](http://mlton.org) (`mlton`, `mllex`, and `mlyacc`). Pre-built binary packages for MLton can be installed via an OS package manager or (for select platforms) obtained from http://mlton.org. + - Supported but not recommended: [SML/NJ](http://www.smlnj.org) (`sml`, `ml-lex`, `ml-yacc`). + * RECOMMENDED: miscellaneous utilities (`git`, `vim`, `time`, `numactl`, `curl`, `jq`, `zip`) + +### Instructions + +The following builds the compiler at `build/bin/mpl`. +``` +$ make all +``` + +After building, MPL can then be installed to `/usr/local`: +``` +$ make install +``` +or to a custom directory with the `PREFIX` option: +``` +$ make PREFIX=/opt/mpl install + + ## Parallel and Concurrent Extensions MPL extends SML with a number of primitives for parallelism and concurrency. From 2bc770031c5a5ddcc88437aa5a62d07db3c1ecb5 Mon Sep 17 00:00:00 2001 From: Jatin Arora Date: Fri, 7 Apr 2023 10:03:17 -0400 Subject: [PATCH 10/10] readme instruction and mention docker --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7cd285422..92a26ea37 100644 --- a/README.md +++ b/README.md @@ -19,14 +19,19 @@ We note, for the artifact reviewers, that MPL does not support entanglement but ## Build and Install (from source) +MPL has only been tested on Linux with x86-64. We list the compilation instructions +and the software requirements below. We also provide a Dockerfile that +you can use to build a docker container, +or just to get commands and references to the software requirements. + ### Requirements -MPL has only been tested on Linux with x86-64. The following software is +The following software is required. * [GCC](http://gcc.gnu.org) * [GMP](http://gmplib.org) (GNU Multiple Precision arithmetic library) * [GNU Make](http://savannah.gnu.org/projects/make), [GNU Bash](http://www.gnu.org/software/bash/) - * binutils (`ar`, `ranlib`, `strip`, ...) + * binutils (`ar`, `ranlib`, `strip`) * Standard ML compiler and tools: - Recommended: [MLton](http://mlton.org) (`mlton`, `mllex`, and `mlyacc`). Pre-built binary packages for MLton can be installed via an OS package manager or (for select platforms) obtained from http://mlton.org. - Supported but not recommended: [SML/NJ](http://www.smlnj.org) (`sml`, `ml-lex`, `ml-yacc`). @@ -46,7 +51,7 @@ $ make install or to a custom directory with the `PREFIX` option: ``` $ make PREFIX=/opt/mpl install - +``` ## Parallel and Concurrent Extensions