js/src/builtin/ParallelUtilities.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/builtin/ParallelUtilities.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,72 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +// Shared utility functions for and macros parallel operations in `Array.js`
     1.9 +// and `TypedObject.js`.
    1.10 +
    1.11 +#ifdef ENABLE_PARALLEL_JS
    1.12 +
    1.13 +/* The mode asserts options object. */
    1.14 +#define TRY_PARALLEL(MODE) \
    1.15 +  ((!MODE || MODE.mode !== "seq"))
    1.16 +#define ASSERT_SEQUENTIAL_IS_OK(MODE) \
    1.17 +  do { if (MODE) AssertSequentialIsOK(MODE) } while(false)
    1.18 +
    1.19 +/**
    1.20 + * The ParallelSpew intrinsic is only defined in debug mode, so define a dummy
    1.21 + * if debug is not on.
    1.22 + */
    1.23 +#ifndef DEBUG
    1.24 +#define ParallelSpew(args)
    1.25 +#endif
    1.26 +
    1.27 +#define MAX_SLICE_SHIFT 6
    1.28 +#define MAX_SLICE_SIZE 64
    1.29 +#define MAX_SLICES_PER_WORKER 8
    1.30 +
    1.31 +/**
    1.32 + * Macros to help compute the start and end indices of slices based on id. Use
    1.33 + * with the object returned by ComputeSliceInfo.
    1.34 + */
    1.35 +#define SLICE_START_INDEX(shift, id) \
    1.36 +    (id << shift)
    1.37 +#define SLICE_END_INDEX(shift, start, length) \
    1.38 +    std_Math_min(start + (1 << shift), length)
    1.39 +
    1.40 +/**
    1.41 + * ForkJoinGetSlice acts as identity when we are not in a parallel section, so
    1.42 + * pass in the next sequential value when we are in sequential mode. The
    1.43 + * reason for this odd API is because intrinsics *need* to be called during
    1.44 + * ForkJoin's warmup to fill the TI info.
    1.45 + */
    1.46 +#define GET_SLICE(sliceStart, sliceEnd, id) \
    1.47 +    ((id = ForkJoinGetSlice((InParallelSection() ? -1 : sliceStart++) | 0)) < sliceEnd)
    1.48 +
    1.49 +/**
    1.50 + * Determine the number and size of slices. The info object has the following
    1.51 + * properties:
    1.52 + *
    1.53 + *  - shift: amount to shift by to compute indices
    1.54 + *  - count: number of slices
    1.55 + */
    1.56 +function ComputeSlicesInfo(length) {
    1.57 +  var count = length >>> MAX_SLICE_SHIFT;
    1.58 +  var numWorkers = ForkJoinNumWorkers();
    1.59 +  if (count < numWorkers)
    1.60 +    count = numWorkers;
    1.61 +  else if (count >= numWorkers * MAX_SLICES_PER_WORKER)
    1.62 +    count = numWorkers * MAX_SLICES_PER_WORKER;
    1.63 +
    1.64 +  // Round the slice size to be a power of 2.
    1.65 +  var shift = std_Math_max(std_Math_log2(length / count) | 0, 1);
    1.66 +
    1.67 +  // Recompute count with the rounded size.
    1.68 +  count = length >>> shift;
    1.69 +  if (count << shift !== length)
    1.70 +    count += 1;
    1.71 +
    1.72 +  return { shift: shift, count: count };
    1.73 +}
    1.74 +
    1.75 +#endif // ENABLE_PARALLEL_JS

mercurial