diff --git a/benchmark/README.md b/benchmark/README.md index 84d30a2d..ac250575 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -36,12 +36,12 @@ Please refer to [execute-scalability.ts](./execute-scalability.ts) for test deta ## Execute overhead The overhead of `zone.execute` includes -1. marshalling cost of arguments in caller thread. -2. queuing time before a worker can execute. -3. unmarshalling cost of arguments in target worker. -4. marshalling cost of return value from target worker. -5. queuing time before caller callback is notified. -6. unmarshalling cost of return value in caller thread. +1. Marshalling cost of arguments in caller thread. +2. Queuing time before a worker can execute. +3. Unmarshalling cost of arguments in target worker. +4. Marshalling cost of return value from target worker. +5. Queuing time before caller callback is notified. +6. Unmarshalling cost of return value in caller thread. In this section we will examine #2 and #5. So we use empty function with no arguments and no return value. @@ -132,12 +132,12 @@ Please refer to [transport-overhead.ts](./transport-overhead.ts) for test detail ## Store access overhead The overhead of `store.set` includes -1. overhead of calling `transport.marshall` on value. -2. overhead of put marshalled data and transport context into C++ map (with exclusive_lock). +1. Overhead of calling `transport.marshall` on value. +2. Overhead of put marshalled data and transport context into C++ map (with exclusive_lock). The overhead of `store.get` includes -1. overhead of getting marshalled data and transport context from C++ map (with shared_lock). -2. overhead of calling `transport.unmarshall` on marshalled data. +1. Overhead of getting marshalled data and transport context from C++ map (with shared_lock). +2. Overhead of calling `transport.unmarshall` on marshalled data. For `store.set`, numbers below indicates the cost beyond marshall is around 0.07~0.4ms varies per payload size. (10B to 18KB). `store.get` takes a bit more: 0.06~0.9ms with the same payload size variance. If the value in store is not updated frequently, it's always good to cache it in JavaScript world. diff --git a/docs/api/transport.md b/docs/api/transport.md index d212c691..e80c1270 100644 --- a/docs/api/transport.md +++ b/docs/api/transport.md @@ -40,7 +40,7 @@ Transportable types are: - JavaScript primitive types: undefined, null, boolean, number, string - Object (TypeScript class) that implement [`Transportable`](#transportable) interface - Function without referencing closures. -- JavaScript standard built-In objects in this whitelist. +- JavaScript standard built-in objects in this whitelist. * ArrayBuffer * Float32Array * Float64Array @@ -54,23 +54,23 @@ Transportable types are: - Array or plain JavaScript object that is composite pattern of above. ### Constructor ID (cid) -For user classes that implement [`Transportable`](#transportable) interface, Napa uses Constructor ID (`cid`) to lookup constructors for creating a right object from a string payload. `cid` is marshalled as a part of the payload. During unmarshalling, transport layer will extract the `cid`, create an object instance using the constructor associated with it, and then call unmarshall on the object. +For user classes that implement the [`Transportable`](#transportable) interface, Napa uses Constructor ID (`cid`) to lookup constructors for creating a right object from a string payload. `cid` is marshalled as a part of the payload. During unmarshalling, the transport layer will extract the `cid`, create an object instance using the constructor associated with it, and then call unmarshall on the object. -It's class developer's responsibility to choose the right `cid` for your class. To avoid conflict, we suggest to use the combination of module.id and class name as `cid`. Developer can use class decorator [`cid`](#decorator-cid) to register a user Transportable class automatically, when using TypeScript with decorator feature enabled. Or call [`transport.register`](#register) manually during module initialization. +It's the class developer's responsibility to choose the right `cid` for your class. To avoid conflict, we suggest to use the combination of module.id and class name as `cid`. Developer can use class decorator [`cid`](#decorator-cid) to register a user Transportable class automatically, when using TypeScript with decorator feature enabled. Or call [`transport.register`](#register) manually during module initialization. ### Transport context -There are states that cannot be saved or loaded in serialized form (like std::shared_ptr), or it's very inefficient to serialize (like JavaScript function). Transport context is introduced to help in these scenarios. TransportContext objects can be passed from one JavaScript VM to another, or stored in native world, so lifecycle of shared native objects extended by using TransportContext. An example of `Transportable` implementation using TransportContext is [`ShareableWrap`](./../../inc/napa/module/shareable-wrap.h). +There are states that cannot be saved or loaded in serialized form (like std::shared_ptr), or it's very inefficient to serialize (like JavaScript function). Transport context is introduced to help in these scenarios. TransportContext objects can be passed from one JavaScript VM to another, or stored in the native world, so lifecycle of shared native objects extended by using TransportContext. An example of the `Transportable` implementation using TransportContext is [`ShareableWrap`](./../../inc/napa/module/shareable-wrap.h). ### Transporting functions JavaScript function is a special transportable type, through marshalling its definition into a [store](./store.md#intro), and generate a new function from its definition on target thread. Highlights on transporting functions are: - For the same function, marshall/unmarshall is an one-time cost on each JavaScript thread. Once a function is transported for the first time, later transportation of the same function to previous JavaScript thread can be regarded as free. -- Closure cannot be transported, but you won't get error when transporting a function. Instead, you will get runtime error complaining a variable (from closure) is undefined when you can the function later. -- `__dirname` / `__filename` can be accessed in transported function, which is determined by `origin` property of function. By default `origin` property is set to current working directory. +- Closure cannot be transported, but you won't get an error when transporting a function. Instead, you will get runtime error complaining a variable (from closure) is undefined when you can the function later. +- `__dirname` / `__filename` can be accessed in transported function, which is determined by `origin` property of the function. By default, `origin` property is set to the current working directory. ### Transporting JavaScript built-in objects -JavaScript standard built-In objects in [the whitelist](#built-in-whitelist) can be transported among napa workers transparently. JavaScript Objects with properties in these types are also able to be transported. Please refer to [unit tests](./../../test/transport-test.ts) for detail. +JavaScript standard built-in objects in [the whitelist](#built-in-whitelist) can be transported among napa workers transparently. JavaScript Objects with properties in these types are also able to be transported. Please refer to [unit tests](./../../test/transport-test.ts) for detail. An example [Parallel Quick Sort](./../../examples/tutorial/parallel-quick-sort) demonstrated transporting TypedArray (created from SharedArrayBuffer) among multiple Napa workers for efficient data sharing. @@ -105,7 +105,7 @@ class B { assert(!transport.isTransportable(new B())); ``` ### register(transportableClass: new(...args: any[]) => any): void -Register a `Transportable` class before transport layer can marshall/unmarshall its instances. +Register a `Transportable` class before the transport layer can marshall/unmarshall its instances. User can also use class decorator [`@cid`](#cid-decorator) for class registration. Example: @@ -121,7 +121,7 @@ class A extends transport.AutoTransportable { transport.register(A); ``` ### marshall(jsValue: any, context: TransportContext): string -Marshall a [transportable](#transportable-types) JavaScript value into a JSON payload with a [`TransportContext`](#transport-context). Error will be thrown if the value is not transportable. +Marshall a [transportable](#transportable-types) JavaScript value into a JSON payload with a [`TransportContext`](#transport-context).An Error will be thrown if the value is not transportable. Example: ```js @@ -132,7 +132,7 @@ var jsonPayload = transport.marshall( console.log(jsonPayload); ``` ### unmarshall(json: string, context: TransportContext): any -Unmarshall an [transportable](#transportable-types) JavaScript value from a JSON payload with a [`TransportContext`](#transport-context). Error will be thrown if `cid` property is found and not registered with transport layer. +Unmarshall a [transportable](#transportable-types) JavaScript value from a JSON payload with a [`TransportContext`](#transport-context).An Error will be thrown if `cid` property is found and not registered with the transport layer. Example: ```js @@ -148,18 +148,18 @@ Save a shareable object in context. Load a shareable object from handle. ### context.sharedCount: number -Count of shareable objects saved in current context. +Count of shareable objects saved in the current context. ## Interface `Transportable` -Interface for Transportable object. +Interface for the Transportable object. ### transportable.cid: string -Get accessor for [Constructor ID](#constructor-id). It is used to lookup constructor for payload of current class. +Get accessor for [Constructor ID](#constructor-id). It is used to lookup constructor for the payload of the current class. ### transportable.marshall(context: TransportContext): object -Marshall transform this object into a plain JavaScript object with the help of [TransportContext](#transport-context). +Marshall transforms this object into a plain JavaScript object with the help of [TransportContext](#transport-context). ### transportable.unmarshall(payload: object, context: TransportContext): void -Unmarshall transform marshalled payload into current object. +Unmarshall transforms marshalled payload into current object. ## Abstract class `TransportableObject` TBD diff --git a/examples/tutorial/estimate-pi-in-parallel/README.md b/examples/tutorial/estimate-pi-in-parallel/README.md index 45ea9476..a910dd35 100644 --- a/examples/tutorial/estimate-pi-in-parallel/README.md +++ b/examples/tutorial/estimate-pi-in-parallel/README.md @@ -4,9 +4,9 @@ This example implements an algorithm to [estimate PI using Monte Carlo method](h In the implementation, multiple batches of points are evaluated simultaneously in a [napa zone](https://github.com/Microsoft/napajs/wiki/introduction#zone) of 4 workers. Results are aggregated to calculate the final PI after all batches finishes. ## How to run -1. Go to directory of "examples/tutorial/estimate-pi-in-parallel" -2. Run "npm install" to install napajs -3. Run "node estimate-pi-in-parallel.js" +1. Go to directory of `examples/tutorial/estimate-pi-in-parallel` +2. Run `npm install` to install napajs +3. Run `node estimate-pi-in-parallel.js` ## Program output The table below shows results of PI calculated under different settings, each setting emulates 4,000,000 points evaluated by a napa zone of 4 workers. diff --git a/examples/tutorial/max-square-sub-matrix/README.md b/examples/tutorial/max-square-sub-matrix/README.md index c48f7e4e..5ee8ae1f 100644 --- a/examples/tutorial/max-square-sub-matrix/README.md +++ b/examples/tutorial/max-square-sub-matrix/README.md @@ -6,9 +6,9 @@ In this implementation, all units to be evaluated were divided into 2 * size of Please note that this example is to demonstrate the programming paradigm, while itself is NOT performance efficient, since each worker does too little CPU operation and major overhead is on communication. ## How to run -1. Go to directory of "examples/tutorial/max-square-sub-matrix" -2. Run "npm install" to install napajs -3. Run "node max-square-sub-matrix.js" +1. Go to directory of `examples/tutorial/max-square-sub-matrix` +2. Run `npm install` to install napajs +3. Run `node max-square-sub-matrix.js` **Note**: This example uses 'async / await', so Node version that supports ES6 is required. (newer than v7.6.0). diff --git a/examples/tutorial/napa-runner/README.md b/examples/tutorial/napa-runner/README.md index 0164e14e..c42c1425 100644 --- a/examples/tutorial/napa-runner/README.md +++ b/examples/tutorial/napa-runner/README.md @@ -2,15 +2,15 @@ Napa runner is an example to embed Napa.JS into a C++ program. It simply runs JavaScript with all Napa capability without Node dependency from command line. ## How to build -1. Go to napajs root directory, run "node build.js embed" to build napa library for embedded mode. +1. Go to napajs root directory and run `node build.js embed` to build napa library for embeded mode. **NOTE**: This step may take about 30 mins, because it will build V8 library from Node. We are using node v6.10.3, a stable version can build as a library. It is specified in [embedded.js](https://github.com/Microsoft/napajs/blob/master/scripts/embedded.js) and [napa-runner CMakeLists.txt](https://github.com/Microsoft/napajs/blob/master/examples/tutorial/napa-runner/CMakeLists.txt). Please update both of them if you want to use a different version of Node/V8. -2. Go to directory of "examples/tutorial/napa-runner", and run "cmake-js build" to build napa runner +2. Go to directory of `examples/tutorial/napa-runner`, and run `cmake-js build` to build napa runner **NOTE**: Build solution of napa-runner is provided only for linux system so far. Windows / Mac OS support will come in near future. ## How to use -1. Run "npm install" to install required npm modules -2. Run "./bin/napa-runner estimate-PI.js" +1. Run `npm install` to intall required npm modules +2. Run `./bin/napa-runner emstimate-PI.js` diff --git a/examples/tutorial/parallel-quick-sort/README.md b/examples/tutorial/parallel-quick-sort/README.md index 269bad58..50df74b7 100644 --- a/examples/tutorial/parallel-quick-sort/README.md +++ b/examples/tutorial/parallel-quick-sort/README.md @@ -4,9 +4,9 @@ This example implements a parallel version of quicksort by napa.js, and compares 2. How does napa.js accelerate a computation heavy task by parallelization. ## How to run -1. Go to directory of "examples/tutorial/parallel-quick-sort" -2. Run "npm install" to install napajs -3. Run "node parallel-quick-sort.js" +1. Go to directory of `examples/tutorial/parallel-quick-sort`. +2. Run `npm install` to install napajs. +3. Run `node parallel-quick-sort.js`. **Note**: This example involves TypedArray and SharedArrayBuffer. It requires Node v9.0.0 or newer. diff --git a/examples/tutorial/recursive-fibonacci/README.md b/examples/tutorial/recursive-fibonacci/README.md index 75df8460..ca0771c0 100644 --- a/examples/tutorial/recursive-fibonacci/README.md +++ b/examples/tutorial/recursive-fibonacci/README.md @@ -6,9 +6,9 @@ Recursion is supported on a single thread by JavaScript language, how if we want Please note that this example is to demonstrate the programming paradigm, while itself is *NOT* performance efficient, since each worker does too little CPU operation (simply '+') and major overhead is on communication. ## How to run -1. Go to directory of "examples/tutorial/recursive-fibonacci" -2. Run "npm install" to install napajs -3. Run "node recursive-fibonacci.js" +1. Go to directory of `examples/tutorial/recursive-fibonacci` +2. Run `npm install`to install napajs +3. Run `node recursive-fibonacci.js` ## Program output Table below shows statistics of calculating Nth Fibonacci number by a napa zone with 4 workers. diff --git a/examples/tutorial/synchronized-loading/README.md b/examples/tutorial/synchronized-loading/README.md index e1acf60e..5160f042 100644 --- a/examples/tutorial/synchronized-loading/README.md +++ b/examples/tutorial/synchronized-loading/README.md @@ -4,9 +4,9 @@ This example implements a shared phone book component. The component will not lo The component is implemented using lazy-loading pattern with the use of [`napa.sync.Lock`](./../../../docs/api/sync.md#interface-lock). ## How to run -1. Go to directory of "examples/tutorial/synchronized-loading" -2. Run "npm install" to install napajs -3. Run "node synchronized-loading.js" +1. Go to directory of `examples/tutorial/synchronized-loading` +2. Run `npm install` to install napajs +3. Run `node synchronized-loading.js` ## Program output The output below shows one possible result. The sequence of the output may be different but the data loading will always run once only.