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