Code Monkey home page Code Monkey logo

mogill / ems Goto Github PK

View Code? Open in Web Editor NEW
595.0 27.0 41.0 1.25 MB

Extended Memory Semantics - Persistent shared object memory and parallelism for Node.js and Python

License: Other

JavaScript 38.71% C 8.55% Python 15.16% C++ 35.89% Makefile 1.27% Shell 0.38% HTML 0.04%
parallel persistent-data-structure persistent-data persistent-memory non-volatile-memory javascript python shared-memory openmp multithreading json json-data ems extended-memory-semantics

ems's Introduction

OSX | Linux | Node 4.1-14.x, Python2/3: Build Status npm version

Extended Memory Semantics (EMS)

EMS makes possible persistent shared memory parallelism between Node.js, Python, and C/C++.

Extended Memory Semantics (EMS) unifies synchronization and storage primitives to address several challenges of parallel programming:

  • Allows any number or kind of processes to share objects
  • Manages synchronization and object coherency
  • Implements persistence to non-volatile memory and secondary storage
  • Provides dynamic load-balancing between processes
  • May substitute or complement other forms of parallelism

Table of Contents

EMS is targeted at tasks too large for one core or one process but too small for a scalable cluster

A modern multi-core server has 16-32 cores and nearly 1TB of memory, equivalent to an entire rack of systems from a few years ago. As a consequence, jobs formerly requiring a Map-Reduce cluster can now be performed entirely in shared memory on a single server without using distributed programming.

Sharing Persistent Objects Between Python and Javascript

Inter-language example in interlanguage.{js,py} The animated GIF demonstrates the following steps:

  • Start Node.js REPL, create an EMS memory
  • Store "Hello"
  • Open a second session, begin the Python REPL
  • Connect Python to the EMS shared memory
  • Show the object created by JS is present in Python
  • Modify the object, and show the modification can be seen in JS
  • Exit both REPLs so no programs are running to "own" the EMS memory
  • Restart Python, show the memory is still present
  • Initialize a counter from Python
  • Demonstrate atomic Fetch and Add in JS
  • Start a loop in Python incrementing the counter
  • Simultaneously print and modify the value from JS
  • Try to read "empty" data from Python, the process blocks
  • Write the empty memory, marking it full, Python resumes execution

Types of Concurrency

EMS extends application capabilities to include transactional memory and other fine-grained synchronization capabilities.

EMS implements several different parallel execution models:
  • Fork-Join Multiprocess: execution begins with a single process that creates new processes when needed, those processes then wait for each other to complete.
  • Bulk Synchronous Parallel: execution begins with each process starting the program at the main entry point and executing all the statements
  • User Defined: parallelism may include ad-hoc processes and mixed-language applications

Built in Atomic Operations

EMS operations may performed using any JSON data type, read-modify-write operations may use any combination of JSON data types. like operations on ordinary data.

Atomic read-modify-write operations are available in all concurrency modes, however collectives are not available in user defined modes.

  • Atomic Operations: Read, write, readers-writer lock, read when full and atomically mark empty, write when empty and atomically mark full

  • Primitives: Stacks, queues, transactions

  • Read-Modify-Write: Fetch-and-Add, Compare and Swap

  • Collective Operations: All basic OpenMP collective operations are implemented in EMS: dynamic, block, guided, as are the full complement of static loop scheduling, barriers, master and single execution regions

Examples and Benchmarks

Word Counting Using Atomic Operations

Word counting example

Map-Reduce is often demonstrated using word counting because each document can be processed in parallel, and the results of each document's dictionary reduced into a single dictionary. This EMS implementation also iterates over documents in parallel, but it maintains a single shared dictionary across processes, atomically incrementing the count of each word found. The final word counts are sorted and the most frequently appearing words are printed with their counts.

The performance of this program was measured using an Amazon EC2 instance:
c4.8xlarge (132 ECUs, 36 vCPUs, 2.9 GHz, Intel Xeon E5-2666v3, 60 GiB memory The leveling of scaling around 16 cores despite the presence of ample work may be related to the use of non-dedicated hardware: Half of the 36 vCPUs are presumably HyperThreads or otherwise shared resource. AWS instances are also bandwidth limited to EBS storage, where our Gutenberg corpus is stored.

Bandwidth Benchmarking

STREAMS Example

A benchmark similar to STREAMS gives us the maximum speed EMS double precision floating point operations can be performed on a c4.8xlarge (132 ECUs, 36 vCPUs, 2.9 GHz, Intel Xeon E5-2666v3, 60 GiB memory.

Benchmarking of Transactions and Work Queues

Transactions and Work Queues Example

Transactional performance is measured alone, and again with a separate process appending new processes as work is removed from the queue. The experiments were run using an Amazon EC2 instance:
c4.8xlarge (132 ECUs, 36 vCPUs, 2.9 GHz, Intel Xeon E5-2666v3, 60 GiB memory

Experiment Design

Six EMS arrays are created, each holding 1,000,000 numbers. During the benchmark, 1,000,000 transactions are performed, each transaction involves 1-5 randomly selected elements of randomly selected EMS arrays. The transaction reads all the elements and performs a read-modify-write operation involving at least 80% of the elements. After all the transactions are complete, the array elements are checked to confirm all the operations have occurred.

The parallel process scheduling model used is block dynamic (the default), where each process is responsible for successively smaller blocks of iterations. The execution model is bulk synchronous parallel, each processes enters the program at the same main entry point and executes all the statements in the program. forEach loops have their normal semantics of performing all iterations, parForEach loops are distributed across threads, each process executing only a portion of the total iteration space.


Immediate Transactions: Each process generates a transaction on integer data then immediately performs it.

Transactions from a Queue: One of the processes generates the individual transactions and appends them to a work queue the other threads get work from. Note: As the number of processes increases, the process generating the transactions and appending them to the work queue is starved out by processes performing transactions, naturally maximizing the data access rate.

Immediate Transactions on Strings: Each process generates a transaction appending to a string, and then immediately performs the transaction.
Measurements
Elem. Ref'd: Total number of elements read and/or written
Table Updates: Number of different EMS arrays (tables) written to
Trans. Performed: Number of transactions performed across all EMS arrays (tables)
Trans. Enqueued: Rate transactions are added to the work queue (only 1 generator thread in these experiments)

EMS internally stores tags that are used for synchronization of user data, allowing synchronization to happen independently of the number or kind of processes accessing the data. The tags can be thought of as being in one of three states, Empty, Full, or Read-Only, and the EMS intrinsic functions enforce atomic access through automatic state transitions.

The EMS array may be indexed directly using an integer, or using a key-index mapping from any primitive type. When a map is used, the key and data itself are updated atomically.



EMS memory is an array of JSON values (Number, Boolean, String, Undefined, or Object) accessed using atomic operators and/or transactional memory. Safe parallel access is managed by passing through multiple gates: First mapping a key to an index, then accessing user data protected by EMS tags, and completing the whole operation atomically.


EMS Data Tag Transitions & Atomic operations: F=Full, E=Empty, X=Don't Care, RW=Readers-Writer lock (# of current readers) CAS=Compare-and-Swap, FAA=Fetch-and-Add

More Technical Information

For a more complete description of the principles of operation, contact the author at [email protected]

Complete API reference


Installation

Because all systems are already multicore, parallel programs require no additional equipment, system permissions, or application services, making it easy to get started. The reduced complexity of lightweight threads communicating through shared memory is reflected in a rapid code-debug cycle for ad-hoc application development.

Quick Start with the Makefile

To build and test all C, Python 2 and 3, and Node.js targets, a makefile can automate most build and test tasks.

dunlin> make help
         Extended Memory Semantics  --  Build Targets
===========================================================
    all                       Build all targets, run all tests
    node                      Build only Node.js
    py                        Build both Python 2 and 3

    py[2|3]                   Build only Python2 or 3
    test                      Run both Node.js and Py tests
    test[_js|_py|_py2|_py3]   Run only Node.js, or only Py tests, respectively
    clean                     Remove all files that can be regenerated
    clean[_js|_py|_py2|_py3]  Remove Node.js or Py files that can be regenerated

Install via npm

EMS is available as a NPM Package. EMS depends on the Node addon API (N-API) package.

npm install ems

Install via GitHub

Download the source code, then compile the native code:

git clone https://github.com/mogill/ems.git
cd ems
npm install

Installing for Python

Python users should download and install EMS git (see above). There is no PIP package, but not due lack of desire or effort. A pull request is most welcome!

Run Some Examples

Click here for Detailed Examples.

On a Mac and most Linux distributions EMS will "just work", but some Linux distributions restrict access to shared memory. The quick workaround is to run jobs as root, a long-term solution will vary with Linux distribution.

Run the work queue driven transaction processing example on 8 processes:

npm run <example>

Or manually via:

cd Examples
node concurrent_Q_and_TM.js 8

Running all the tests with 8 processes:

npm run test      # Alternatively: npm test
cd Tests
rm -f EMSthreadStub.js   # Do not run the machine generated script used by EMS
for test in `ls *js`; do node $test 8; done

Platforms Supported

As of 2016-05-01, Mac/Darwin and Linux are supported. A windows port pull request is welcomed!

Roadmap

EMS 1.0 uses Nan for long-term Node.js support, we continue to develop on OSX and Linux via Vagrant.

EMS 1.3 introduces a C API.

EMS 1.4 Python API

EMS 1.4.8 Improved examples and documentation

EMS 1.5 Refactored JS-EMS object conversion temporary storage

EMS 1.6 [This Release] Updated to replace deprecated NodeJS NAN API with the N-API.

EMS 1.7 [Planned] Key deletion that frees all resources. Replace open hashing with chaining.

EMS 1.8 [Planned] Memory allocator based on R. Marotta, M. Ianni, A. Scarselli, A. Pellegrini and F. Quaglia, "NBBS: A Non-Blocking Buddy System for Multi-core Machines," 2019 19th IEEE/ACM International Symposium on Cluster, Cloud and Grid Computing (CCGRID), Larnaca, Cyprus, 2019, pp. 11-20, doi: 10.1109/CCGRID.2019.00011.

EMS 1.9 [Planned] Vectorized JSON indexer.

EMS 1.10 [Planned] Support for persistent main system memory (PMEM) when multiple processes are supported.

EMS 2.0 [Planned] New API which more tightly integrates with ES6, Python, and other dynamically typed languages languages, making atomic operations on persistent memory more transparent.

License

BSD, other commercial and open source licenses are available.

Links

API Documentation

EMS Website

Download the NPM

Get the source at GitHub

About

Jace A Mogill specializes in hardware/software co-design of resource constrained computing at both the largest and smallest scales. He has over 20 years experience with distributed, multi-core, FPGA, CGRA, GPU, CPU, and custom computer architectures.

Copyright (C)2011-2020 Jace A Mogill

ems's People

Contributors

aleksb avatar asilvas-godaddy avatar mk-pmb avatar mogill avatar msavva avatar trejgun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ems's Issues

Assertion `0' failed

After working for a while loading data and updating them, with write (), it is giving me the following error, how is it solved?
Thank you

node: ../src/ems_alloc.cc:185: void emsMem_free(emsMem*, size_t): Assertion `0' failed.
Aborted (core dumped)

How to free up memory?

Is it possible to delete keys from an EMS array object that uses key-index mapping? Presumably, this would free up memory when certain items are no longer needed. Nodejs 'delete' does not do anything here as far as I can tell.

Survey Question on the For loop in source file Tests/accum_omp.c line 52

Hello Sir/ Madam
We are from a research group at Iowa State University, USA. We want to do a survey on Github developers on the methods they used for paralleling their code. To do the survey, We want to ask three questions:

  1. Have you ever tried to add pragma for that 'for' loop?.

  2. How much confidence do you have about the correctness of this implementation? You can choose from 1-5 with 1 as the lowest confidence score and 5 as the highest confidence.

  3. (Optional) Do you actually run (interpret the code with compilation and pass input/get output) the code? Yes/No

  • If yes, can you provide the information of what are the input and expected output of this program (the input that caused the program to run through this for-loop).

The for loop is from line 52 of file https:/github.com/mogill/ems/blob/master/Tests/accum_omp.c
Here is a part of the code:

nan
for (i = 0; i < 3200; i++)
{
sum += a[i];
}

Sincerely thanks

kv_store seems to limit "clusters" module to one core

Hi,

I did some testing using Examples\kv_store.js as a starting point. And even if I was not using any of the ems function (other than initializing it), the cluster module suddenly was not able to do more than one core's worth of cpu, even though I could see it had several slave processes running.

It do seem to be related to the "threadAffinity" option of ems. When I set this to false in the initialization, it seems that 'cluster' recovers its powers.

Isn't it weird to make an example use the node js cluster module, but limit its strength back to where you would be without it. (or in fact worse)

unexpected JSON format!

Hello,

We are using ems in a multiple process environment using nodjs, this is a small embedded computer which fetches data from multiple ports converts them and sends to another port.

We are randomly getting an error which is a JSON parse error on a saved memory object when we read it using the key. The object is accessed at many places and we are doing just read and write operations on these objects.

Here is the screen shot of the error.

Is this something to do with we are running out of memory? If so how come other operations continue?

By the way what we have in the shared memory is the set of JSON objects (read from a configuration file, some of them have an attribute called value(which is simple type mostly) are of type array of 200 odd integers.

we initialise ems like this (common file sharedMem.js)

`var ems = require('ems')(1, false, 'user');

var persistent_data;

var persistent_data_options = {
dimensions: [50000],
heapSize: [50000000],
useExisting: true,
useMap: true,
setFEtags: 'full',
filename: '/tmp/persistent_shared_web_data.ems'
};

module.exports = {
sharedMem : ems.new(persistent_data_options)
}
`
we use sharedMem in clients

var persistent_data = require('./sharedMem').sharedMem; //somewhere down the line prm = persistent_data.read(currPrm.name); //or write
main module (master since we are using cluster) initialisation is done as follows

var persistent_data_options = { dimensions: [50000], heapSize: [50000000], useExisting: false, useMap: true, setFEtags: 'full', filename: '/tmp/persistent_shared_web_data.ems' };

Here is the error
error

Any help in this regard will be greatly appreciated.

Regards,
Prasanna

Clarify what kinds of data can be shared.

The readme states

EMS operations may performed using any JSON data type, read-modify-write operations may use any combination of JSON data types. like operations on ordinary data.

… but I'm not sure whether I should read that as a limitation, or the guaranteed minimal set that works in all circumstance. For example: Is it possible to share python functions with other python processes, or JS functions from one NodeJS with other NodeJS instances?

Killing child threads

Is there a way to exit all threads that are not the master thread? In other words this is what I want to do:

  1. Create child threads
  2. Do work
  3. Exit child threads
  4. The main thread continues to run

EMS crash with JSON objects saved

Hello,

ems is initialised in multiprocess environment

if (cluster.isMaster) {
var start = Date.now();
var persistent_data_options = {
dimensions: [100000],
heapSize: [10000000],
useExisting: false,
useMap: true,
setFEtags: 'full',
filename: '/tmp/persistent_shared_web_data.ems'
};
....
}

in other process the useExisting flag is true

I add JSON objects (28 in number with fairly small structure of object) all is well till now.

With 29th object in array I get following error

SyntaxError: Unexpected token `
at Object.parse (native)
at EMSreturnData (/home/telemon/node_modules/ems/nodejs/ems.js:211:25)
at Object.EMSread [as read] (/home/telemon/node_modules/ems/nodejs/ems.js:308:12)

when I try to read it returns a partial object string

{"name":"FSM1","mbAddress":0,"mbSize":17,"` - notice the last quote

with

SyntaxError: Unexpected token `

please let me know how do I resolve this?

typedarrays / buffers?

wondering if it's within reasonable effort to read/write typedarrays/buffers? I can see everything goes through JSON stringify & parse, is this a hard constraint or just convention?

@mogill, are you implying here #20 that there's something inherently wrong with buffers in node or just sharedbuffers? ems far outshines anything possible with master-worker shared mem, would love to hear a few more of your thoughts on all this...

hello world using python and nodejs

Hello
Could you help me do the same thing as in the gift inside readme, aka communicate between modems and python?
I'm lost in the documents and I could not find what should I do.
Thanks

This doesn't seem to compile for me on NodeJS 0.12.1 on OSX

CXX(target) Release/obj.target/ems/ems.o
../ems.cpp:250:5: error: use of undeclared identifier 'nanosleep'
NANOSLEEP;
^
../ems.cpp:155:5: note: expanded from macro 'NANOSLEEP'
nanosleep(&sleep_time, NULL);
^
../ems.cpp:265:5: error: use of undeclared identifier 'nanosleep'
NANOSLEEP;
^
../ems.cpp:155:5: note: expanded from macro 'NANOSLEEP'
nanosleep(&sleep_time, NULL);
^
../ems.cpp:352:7: error: use of undeclared identifier 'nanosleep'
NANOSLEEP;
^
../ems.cpp:155:5: note: expanded from macro 'NANOSLEEP'
nanosleep(&sleep_time, NULL);
^
../ems.cpp:392:32: error: no type named 'Arguments' in namespace 'v8'; did you mean 'v8::internal::Arguments'?
uint64_t EMSreadIndexMap(const v8::Arguments& args)
^~~~~~~~~~~~~
v8::internal::Arguments
/var/folders/mr/cr6pnwvs5578w22byhjcxkgc0000gn/T/.node-gyp/0.12.1/deps/v8/include/v8.h:127:7: note: 'v8::internal::Arguments' declared here
class Arguments;
^
../ems.cpp:394:19: error: calling a protected constructor of class 'v8::HandleScope'
v8::HandleScope scope;
^
/var/folders/mr/cr6pnwvs5578w22byhjcxkgc0000gn/T/.node-gyp/0.12.1/deps/v8/include/v8.h:816:13: note: declared protected here
V8_INLINE HandleScope() {}
^
../ems.cpp:395:3: error: unexpected namespace name 'Buffer': expected expression
EMS_DECL(args);
^
../ems.cpp:325:9: note: expanded from macro 'EMS_DECL'
node::Buffer buffer = node::ObjectWrap::Unwrapnode::Buffer(args.This()->GetHiddenValue(buffer_symbol)->ToObject());
^
../ems.cpp:395:3: error: use of undeclared identifier 'buffer'
../ems.cpp:325:17: note: expanded from macro 'EMS_DECL'
node::Buffer *buffer = node::ObjectWrap::Unwrapnode::Buffer(args.This()->GetHiddenValue(buffer_symbol)->ToObject());
^
../ems.cpp:395:3: error: no member named 'ObjectWrap' in namespace 'node'
EMS_DECL(args);
^~~~~~~~~~~~~~
../ems.cpp:325:32: note: expanded from macro 'EMS_DECL'
node::Buffer *buffer = node::ObjectWrap::Unwrapnode::Buffer(args.This()->GetHiddenValue(buffer_symbol)->ToObject());
~~~~~~^
../ems.cpp:395:3: error: unexpected namespace name 'Buffer': expected expression
../ems.cpp:325:57: note: expanded from macro 'EMS_DECL'
node::Buffer *buffer = node::ObjectWrap::Unwrapnode::Buffer(args.This()->GetHiddenValue(buffer_symbol)->ToObject());
^
../ems.cpp:395:3: error: member access into incomplete type 'const v8::internal::Arguments'
../ems.cpp:325:69: note: expanded from macro 'EMS_DECL'
node::Buffer *buffer = node::ObjectWrap::Unwrapnode::Buffer(args.This()->GetHiddenValue(buffer_symbol)->ToObject());
^
/var/folders/mr/cr6pnwvs5578w22byhjcxkgc0000gn/T/.node-gyp/0.12.1/deps/v8/include/v8.h:127:7: note: forward declaration of 'v8::internal::Arguments'
class Arguments;
^
../ems.cpp:395:3: error: use of undeclared identifier 'buffer'
EMS_DECL(args);
^
../ems.cpp:326:40: note: expanded from macro 'EMS_DECL'
char
emsBuf = static_cast<char*>(buffer->handle_->GetIndexedPropertiesExternalArrayData())
^
../ems.cpp:402:46: error: type 'const v8::internal::Arguments' does not provide a subscript operator
int idxType = EMSv8toEMStype(args[0], false);
~~~~^~
../ems.cpp:224:4: note: expanded from macro 'EMSv8toEMStype'
arg->IsInt32() ? EMS_INTEGER :
^
../ems.cpp:402:46: error: type 'const v8::internal::Arguments' does not provide a subscript operator
int idxType = EMSv8toEMStype(args[0], false);
~~~~^~
../ems.cpp:225:4: note: expanded from macro 'EMSv8toEMStype'
arg->IsNumber() ? EMS_FLOAT :
^
../ems.cpp:402:46: error: type 'const v8::internal::Arguments' does not provide a subscript operator
int idxType = EMSv8toEMStype(args[0], false);
~~~~^~
../ems.cpp:226:5: note: expanded from macro 'EMSv8toEMStype'
(arg->IsString() && !stringIsJSON) ? EMS_STRING :
^
../ems.cpp:402:46: error: type 'const v8::internal::Arguments' does not provide a subscript operator
int idxType = EMSv8toEMStype(args[0], false);
~~~~^~
../ems.cpp:227:5: note: expanded from macro 'EMSv8toEMStype'
(arg->IsString() && stringIsJSON) ? EMS_JSON :
^
../ems.cpp:402:46: error: type 'const v8::internal::Arguments' does not provide a subscript operator
int idxType = EMSv8toEMStype(args[0], false);
~~~~^~
../ems.cpp:228:4: note: expanded from macro 'EMSv8toEMStype'
arg->IsBoolean() ? EMS_BOOLEAN :
^
../ems.cpp:402:46: error: type 'const v8::internal::Arguments' does not provide a subscript operator
int idxType = EMSv8toEMStype(args[0], false);
~~~~^~
../ems.cpp:229:4: note: expanded from macro 'EMSv8toEMStype'
arg->IsUndefined() ? EMS_UNDEFINED:
^
../ems.cpp:402:46: error: type 'const v8::internal::Arguments' does not provide a subscript operator
int idxType = EMSv8toEMStype(args[0], false);
~~~~^~
../ems.cpp:230:4: note: expanded from macro 'EMSv8toEMStype'
arg->IsUint32() ? EMS_INTEGER : -1
^
../ems.cpp:409:39: error: type 'const v8::internal::Arguments' does not provide a subscript operator
v8::String::Utf8Value argString(args[0]);
~~~~^~
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
make: *** [Release/obj.target/ems/ems.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: make failed with exit code: 2
gyp ERR! stack at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:269:23)
gyp ERR! stack at ChildProcess.emit (events.js:110:17)
gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:1067:12)
gyp ERR! System Darwin 14.0.0
gyp ERR! command "node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "build"
gyp ERR! cwd /Users/eugene/node-jpeg-turbo-scaler-master/node_modules/ems/ems
gyp ERR! node -v v0.12.1
gyp ERR! node-gyp -v v1.0.3
gyp ERR! not ok

Fork-join threading type does not work

setting the threading type to 'fj' prints the following error:

code:

var ems = require('ems')(8, true, 'fj');

console:
node test.js
> EMS: Must declare number of nodes to use. Input:NaN

potential GCC optimizations based on undefined behaviour

Hi there, great library.

I have briefly looked into the code, and I have stumbled some potential problem with emsMem struct.

ems struct is declared as :

struct emsMem {
int32_t level;
uint8_t tree[1];
};

but tree is not an array of one byte, it is actually a slice of a bigger array allocated in emsMem_new:

struct emsMem *self = (struct emsMem *) malloc(sizeof(struct emsMem) + sizeof(uint8_t) * (size * 2 - 2));

yet, what GCC see in other functions is basically access to tree as uint8_t(*)[1], for example

self->tree[index] == BUDDY_UNUSED

where index can be any number.

for GCC, this is undefined behavior if index != 0 (and it is, for most cases ) , even though tree is a valid allocated block, but tree is declared as uint8_t[1].

GCC is known to use optimizations that rely on undefined behavior. an improvement is to turn tree from uint8_t[1] to uint8_t*. for GCC, it cannot determine if tree[index] is undefined behavior or not at compile time, thus minimizing the possibility of undefined-behavior based optimizations.

Bug memory leak when used to run custom next.js server.

We made a custom server for next.js.

and adopted esm using es import and export syntax.

but esm make built pages each request and not free.

So we adopted babel-core & babel-cli to custom server instead of esm.

I hope you will fight with code without suffering.

Good luck!

Instantiating unbounded EMS array

Is it possible to instantiate an EMS array object without specifying it's dimension? I'm at a case where I do not know how big the array will be.

NPM Install Fails

After running "npm install ems"

I get a bunch of errors like:
../src/ffi.cc:126:11: error: ‘class v8::Object’ has no member named ‘ForceSet’

Word Count Example

In your word count example the following line:

var text = fs.readFileSync('/Data/Gutenberg/all/' + dir[bufNum], 'utf8', "r")

should be:

var text = fs.readFileSync('/Data/Gutenberg/all/' + dir[docNum], 'utf8', "r")

Refactor mapped indexes

Mapped indexes are implemented using a secondary address translation lookup from an ordinary EMS array. As a consequence, 'empty' target data at startup cannot be initialized.

Survey Question on the For loop in source file accum_omp.c line 45

Hello Sir/ Madam
We are from a research group at Iowa State University, USA. We want to do a survey on Github developers on the methods they used for paralleling their code. To do the survey, We want to ask three questions about this for loop:

Can you briefly explain the purpose of using pragma for this case? If the pragma contained reduction and private clauses, can you briefly mention the purposes of variables in those clauses?

How much confidence do you have about the correctness of this implementation? You can choose from 1-5 with 1 as the lowest confidence score and 5 as the highest confidence score.

(Optional) Do you actually run (interpret the code with compilation and pass input/get output) the code and see the optimization of parallelization? Yes/No

If yes, can you provide the information of what are the input and expected output of this program (the input that caused the program to run through this for-loop).
The for loop is from line 45 of file
https://github.com/mogill/ems/blob/master/Tests/accum_omp.c

for (i = 0; i < 100000000; i++)
{
int retval = __sync_fetch_and_add(&a[i % 3200], 1);
}

EMS: Must declare number of nodes to use. Input:NaN

Hi,

This situation was mentioned in #10, here is the code, but this time around I don't have any shared state with the spawning process:

index.js:

const ems = require('ems')(4, false, 'fj')

ems.parallel(function () {
    var x = 1
        console.log(x)
})

process.exit(0)

Running node index.js yields:

1
EMS: Must declare number of nodes to use.  Input:NaN
EMS: Must declare number of nodes to use.  Input:NaN
EMS: Must declare number of nodes to use.  Input:NaN

Running node index.js 4 yields:

1
1
1
1

Node version is v5.5.0

Anything I missed?

Key Deletion and Memory Leak

The open-hashing scheme used to resolve key collisions means there is more than one possible place to find a key. Resolving insertion collisions is not atomic, resulting in race hazards when deletions create new places to find a key.

Deletion in EMS is implemented as overwriting the value of the key, the key itself is never freed. Although this makes insertion deterministic, it leaks memory and hash map entries. The key itself is stored on the EMS heap when the key is written, or as a result of a read-modify-write, including modification of tag bits. That is, if the key foo does not already exist, readFF("foo") will store the key foo on the EMS heap, and it is possible to consume all the entries in the hash map by reading keys that have undefined values.

In EMS 1.x the solution is to replace the open hashing scheme with hashing with chaining where collisions are resolved by chaining performed sequentially (ie: while holding a per hash element lock).

In EMS 2.x the internal heap data structure will use both hash lookup and linked lists.

N-API

N-API port to insulate from engine changes (#20)

Future of EMS

Hi! I was shocked to see today that our docs are broken (images + API Documentation + EMS Website) and EMS is going to die for Node.js. I've rather limited funds and I usually avoid C(++), can I help in some other way? Looking at http://syntheticsemantics.com/ it indeed seems it's used mostly by people who know how to set up proper caching. ;-) Or do people just not need the performance anymore and prefer a broker like AMQP instead?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.