diff options
| author | Steinar H. Gunderson <sgunderson@bigfoot.com> | 2014-04-11 19:25:59 +0200 | 
|---|---|---|
| committer | Steinar H. Gunderson <sgunderson@bigfoot.com> | 2014-04-11 19:25:59 +0200 | 
| commit | 84a7679ff3ede9b9bce08a144e9a5fe38a13047c (patch) | |
| tree | 9d39e8cc83bbc3c2b011d2e621689b1f43742e01 | |
| parent | e8654a9006abc80ac00ab0336da0dd0c927dd985 (diff) | |
Support multithreaded distro optimization.
| -rw-r--r-- | planning/planning.cpp | 47 | 
1 files changed, 41 insertions, 6 deletions
diff --git a/planning/planning.cpp b/planning/planning.cpp index 9df7074..eb6d2a5 100644 --- a/planning/planning.cpp +++ b/planning/planning.cpp @@ -5,7 +5,7 @@  // Given D distro switches and N access switches, complexity is approx. O(dn³)  // (runs n iterations, each iteration is O(VE), V is O(n), E is O(dn))).  // -// g++ -std=gnu++11 -Wall -g -O2 -DOUTPUT_FILES=1 -o planning planning.cpp && ./planning -3 -6 11 22 -26 35 +// g++ -std=gnu++11 -Wall -g -O3 -fopenmp -DOUTPUT_FILES=1 -o planning planning.cpp && ./planning -3 -6 11 22 -26 35  #include <stdio.h>  #include <math.h> @@ -19,6 +19,7 @@  #include <netinet/in.h>  #include <arpa/inet.h> +#include <atomic>  #include <vector>  #include <map>  #include <string> @@ -672,7 +673,7 @@ int Planner::do_work(int distro_placements[NUM_DISTRO])  	return total_cost;  } -void plan_recursively(int distro_placements[NUM_DISTRO], int distro_num, int min_placement, int max_placement, int *best_cost) +void plan_recursively(int distro_placements[NUM_DISTRO], int distro_num, int min_placement, int max_placement, atomic<int> *best_cost)  {  	if (distro_num == NUM_DISTRO) {  		string log; @@ -681,10 +682,15 @@ void plan_recursively(int distro_placements[NUM_DISTRO], int distro_num, int min  		p.set_log_buf(&log);  		int cost = p.do_work(distro_placements); -		if (cost >= *best_cost) { +try_again: +		int old_best_cost = best_cost->load(); +		if (cost >= old_best_cost) {  			return;  		} -		*best_cost = cost; +		if (!best_cost->compare_exchange_weak(old_best_cost, cost)) { +			// Someone else changed the value in the meantime. +			goto try_again; +		}  		for (unsigned i = 0; i < NUM_DISTRO; ++i) {  			printf("%d ", distro_placements[i]);  		} @@ -717,9 +723,38 @@ int main(int argc, char **argv)  	printf("%s\n", log.c_str());  	return 0;  #else -	int best_cost = _INF * 1000; +	atomic<int> best_cost(_INF * 1000);  	distro_placements[0] = -3;  // obvious -	plan_recursively(distro_placements, 1, 6, NUM_ROWS, &best_cost); + +	constexpr int min_placement = 6; +	constexpr int max_placement = NUM_ROWS; + +	// Boring single-threaded version +	// plan_recursively(distro_placements, 1, min_placement, max_placement, &best_cost); + +	#pragma omp parallel for schedule(dynamic,1) collapse(2) +	for (int i = min_placement; i <= max_placement; ++i) { +		for (int j = min_placement; j <= max_placement; ++j) { +			if (j <= i) continue; + +			int new_distro_placements[NUM_DISTRO]; +			memcpy(new_distro_placements, distro_placements, sizeof(distro_placements)); + +			new_distro_placements[1] = i; + +			new_distro_placements[2] = j; +			plan_recursively(new_distro_placements, 3, j + 1, max_placement, &best_cost); +			new_distro_placements[2] = -j; +			plan_recursively(new_distro_placements, 3, j + 1, max_placement, &best_cost); + +			new_distro_placements[1] = -i; +			new_distro_placements[2] = j; +			plan_recursively(new_distro_placements, 3, j + 1, max_placement, &best_cost); +			new_distro_placements[2] = -j; +			plan_recursively(new_distro_placements, 3, j + 1, max_placement, &best_cost); +		} +	} +  	return 0;  #endif  }  | 
