#include <unistd.h>
#include <stdbool.h>
#include <inttypes.h>
+#include <math.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/uio.h>
static glp_prob *best_prob;
static AdjWord *best_adjmatrix;
+static int n_over_best;
+static int *weight;
+
static unsigned printcounter;
static void iterate(void);
fflush(stderr);
}
+static void set_best(double new_best) {
+ best = new_best;
+ n_over_best = floor(n / best);
+}
+
/*----- multicore support -----*/
/*
static void multicore_check_for_new_best(void);
-#define MAX_NIOVS 3
+#define MAX_NIOVS 4
static AdjWord mc_iter_min;
static int mc_niovs;
static size_t mc_iovlen;
IOV(maxhamweight, 1);
IOV(mc_iter_min, 1);
IOV(*adjmatrix, multicore_iteration_boundary);
+ IOV(*weight, m);
}
static void mc_rwvsetup_full(void) {
}
static void multicore_outer_iteration(int i, AdjWord min) {
+ static unsigned check_counter;
+
assert(i == multicore_iteration_boundary);
mc_iter_min = min;
mc_rwvsetup_outer();
assert(r == mc_iovlen);
/* effectively, this writev arranges to transfers control
* to some worker's instance of iterate_recurse via mc_iterate_worker */
+
+ if (!(check_counter++ & 0xff))
+ multicore_check_for_new_best();
}
static void mc_iterate_worker(void) {
if (!got) break;
assert(got == sizeof(msg));
if (msg > best)
- best = msg;
+ set_best(msg);
mc_bus_read += sizeof(msg);
}
}
adjmatrix = xalloc_adjmatrix();
glp_term_out(GLP_OFF);
setlinebuf(stderr);
+ weight = calloc(sizeof(*weight), m); assert(weight);
+ n_over_best = INT_MAX;
}
static AdjWord one_adj_bit(int bitnum) {
HAVE_PRINTED;
- best = got;
+ set_best(got);
multicore_found_new_best();
if (best_prob) glp_delete_prob(best_prob);
if (i == 0 && (adjmatrix[i] & (1+adjmatrix[i])))
goto again;
+ for (int j = 0; j < m; j++)
+ if (adjmatrix[i] & one_adj_bit(j))
+ weight[j]++;
+ for (int j = 0; j < m; j++)
+ if (weight[j] >= n_over_best)
+ goto takeout;
+
iterate_recurse(i+1, adjmatrix[i]);
+ takeout:
+ for (int j = 0; j < m; j++)
+ if (adjmatrix[i] & one_adj_bit(j))
+ weight[j]--;
+
again:
if (adjmatrix[i] == adjall)
return;