diff --git a/squiggle_more.c b/squiggle_more.c index 5d7d75b..740f8e4 100644 --- a/squiggle_more.c +++ b/squiggle_more.c @@ -60,13 +60,13 @@ void sampler_parallel(double (*sampler)(uint64_t* seed), double* results, int n_ } int i; -#pragma omp parallel private(i, quotient) +#pragma omp parallel private(i) { -#pragma omp for +#pragma omp for for (i = 0; i < n_threads; i++) { - int quotient = n_samples / n_threads; int lower_bound_inclusive = i * quotient; int upper_bound_not_inclusive = ((i + 1) * quotient); // note the < in the for loop below, + for (int j = lower_bound_inclusive; j < upper_bound_not_inclusive; j++) { results[j] = sampler(&(cache_box[i].seed)); // In principle, these results[j] could also result in two threads competing for the same cache line. @@ -75,6 +75,23 @@ void sampler_parallel(double (*sampler)(uint64_t* seed), double* results, int n_ // b) trying to unroll loops actually makes the code slower // c) 8 results[j] are 8 doubles, which fit a cache line. If n_samples/n_threads } + // Failed loop unrolling + /* + for (int j = lower_bound_inclusive; j < 4*(upper_bound_not_inclusive/4); j++) { + results[j+0] = sampler(&(cache_box[i].seed)); + results[j+1] = sampler(&(cache_box[i].seed)); + results[j+2] = sampler(&(cache_box[i].seed)); + results[j+3] = sampler(&(cache_box[i].seed)); + // In principle, these results[j] could also result in two threads competing for the same cache line. + // In practice, though, + // a) this would happen infrequently + // b) trying to unroll loops actually makes the code slower + // c) 8 results[j] are 8 doubles, which fit a cache line. If n_samples/n_threads + } + for (int j = 4*(upper_bound_not_inclusive/4); j < upper_bound_not_inclusive; j++) { + results[j] = sampler(&(cache_box[i].seed)); + } + */ } } for (int j = divisor_multiple; j < n_samples; j++) { @@ -92,7 +109,7 @@ typedef struct ci_t { double high; } ci; -static void swp(int i, int j, double xs[]) +inline static void swp(int i, int j, double xs[]) { double tmp = xs[i]; xs[i] = xs[j];