diff --git a/src/vec.cpp b/src/vec.cpp index 8b1663da2..67b88380a 100644 --- a/src/vec.cpp +++ b/src/vec.cpp @@ -1029,7 +1029,7 @@ std::complex grid_volume::get_split_costs(direction d, int split_point) static double cost_diff(int desired_chunks, std::complex costs) { double left_cost = real(costs), right_cost = imag(costs); - return right_cost / (desired_chunks - desired_chunks / 2) - left_cost / (desired_chunks / 2); + return right_cost - left_cost * (desired_chunks-1); } void grid_volume::find_best_split(int desired_chunks, int &best_split_point, @@ -1072,8 +1072,7 @@ void grid_volume::find_best_split(int desired_chunks, int &best_split_point, std::complex costs = get_split_costs(d, split_point); double left_cost = real(costs), right_cost = imag(costs); double total_cost = left_cost + right_cost; - double split_measure = - max(left_cost / (desired_chunks / 2), right_cost / (desired_chunks - desired_chunks / 2)); + double split_measure = max(left_cost * (desired_chunks-1), right_cost); if (split_measure < best_split_measure) { if (d == longest_axis || split_measure < (best_split_measure - (0.3 * best_split_measure))) { // Only use this split_measure if we're on the longest_axis, or if the split_measure is @@ -1127,77 +1126,29 @@ grid_volume grid_volume::split_by_cost(int desired_chunks, int proc_num, int bes } void grid_volume::split_into_three(std::vector &result) const { - - grid_volume best_low, best_mid, best_high; - double best_overall_split_measure = 1e20; - int best_low_split_point = 0; - int best_high_split_point = 0; - - double total_cost = get_cost(); - double ideal_cost_per_chunk = total_cost / 3; - - direction longest_axis = NO_DIRECTION; - int num_in_longest_axis = 0; - LOOP_OVER_DIRECTIONS(dim, d) { - if (num_direction(d) > num_in_longest_axis) { - longest_axis = d; - num_in_longest_axis = num_direction(d); - } - } - - LOOP_OVER_DIRECTIONS(dim, d) { - double best_low_split_measure = 1e20; - for (int split_point = 1; split_point < num_direction(d); ++split_point) { - grid_volume v_low = *this; - v_low.set_num_direction(d, split_point); - double low_cost = v_low.get_cost(); - double split_measure = fabs(low_cost - ideal_cost_per_chunk); - - if (split_measure < best_low_split_measure) { - best_low_split_measure = split_measure; - best_low_split_point = split_point; - } - } - - grid_volume low_gv = split_at_fraction(false, best_low_split_point, d, num_direction(d)); - grid_volume high_two_gvs = split_at_fraction(true, best_low_split_point, d, num_direction(d)); - - double best_high_split_measure = 1e20; - for (int split_point = 1; split_point < high_two_gvs.num_direction(d); ++split_point) { - grid_volume v_low = high_two_gvs; - v_low.set_num_direction(d, split_point); - double low_cost = v_low.get_cost(); - double split_measure = fabs(low_cost - ideal_cost_per_chunk); - - if (split_measure < best_high_split_measure) { - best_high_split_measure = split_measure; - best_high_split_point = split_point; - } - } - grid_volume mid_gv = high_two_gvs.split_at_fraction(false, best_high_split_point, d, - high_two_gvs.num_direction(d)); - grid_volume high_gv = high_two_gvs.split_at_fraction(true, best_high_split_point, d, - high_two_gvs.num_direction(d)); - - double low_cost = low_gv.get_cost(); - double mid_cost = mid_gv.get_cost(); - double high_cost = high_gv.get_cost(); - - double overall_split_measure = max(max(low_cost, mid_cost), high_cost); - bool within_thirty_percent = (overall_split_measure > best_overall_split_measure * 0.7 && - overall_split_measure < best_overall_split_measure * 1.3); - bool at_least_thirty_percent_better = overall_split_measure < best_overall_split_measure * 0.7; - - if ((within_thirty_percent && d == longest_axis) || at_least_thirty_percent_better) { - best_overall_split_measure = overall_split_measure; - best_low = low_gv; - best_mid = mid_gv; - best_high = high_gv; - } - } - result.push_back(best_low); - result.push_back(best_mid); - result.push_back(best_high); + int best_low_split_point; + direction best_low_split_direction; + double left_effort_fraction; + find_best_split(3, best_low_split_point, best_low_split_direction, left_effort_fraction); + + grid_volume low_gv = split_at_fraction(false, best_low_split_point, best_low_split_direction, + num_direction(best_low_split_direction)); + grid_volume high_two_gvs = split_at_fraction(true, best_low_split_point, best_low_split_direction, + num_direction(best_low_split_direction)); + + int best_high_split_point; + direction best_high_split_direction; + double right_effort_fraction; + high_two_gvs.find_best_split(2, best_high_split_point, best_high_split_direction, right_effort_fraction); + + grid_volume mid_gv = high_two_gvs.split_at_fraction(false, best_high_split_point, best_high_split_direction, + high_two_gvs.num_direction(best_high_split_direction)); + grid_volume high_gv = high_two_gvs.split_at_fraction(true, best_high_split_point, best_high_split_direction, + high_two_gvs.num_direction(best_high_split_direction)); + + result.push_back(low_gv); + result.push_back(mid_gv); + result.push_back(high_gv); } std::vector grid_volume::split_into_n(int n) const {