nissy-core

The "engine" of nissy, including the H48 optimal solver.
git clone https://git.tronto.net/nissy-core
Download | Log | Files | Refs | README | LICENSE

distribution_h48.h (2244B)


      1 /*
      2 This file is very similar to ../distibution.h, but some adaptations are
      3 needed for H48 because of the intertwined fallback table, and it is easier
      4 to have some duplication than to make these functions needlessly generic.
      5 */
      6 
      7 STATIC void *getdistribution_h48_runthread(void *);
      8 STATIC void getdistribution_h48(const unsigned char *,
      9     uint64_t [static INFO_DISTRIBUTION_LEN], const tableinfo_t [static 1]);
     10 
     11 STATIC void *
     12 getdistribution_h48_runthread(void *arg)
     13 {
     14 	getdistribution_data_t *data = (getdistribution_data_t *)arg;
     15 	const unsigned char *table;
     16 	uint8_t j, k, m;
     17 	uint64_t line, d;
     18 	unsigned char t;
     19 
     20 	memset(data->distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t));
     21 
     22 	k = data->bits;
     23 	table = data->table;
     24 	m = TABLE_MASK(0, k);
     25 	for (line = data->min; line < data->max; line++) {
     26 		for (d = 0; d < H48_LINE_BYTES; d++) {
     27 			t = table[d + line * H48_LINE_BYTES];
     28 			for (j = 0; j < ENTRIES_PER_BYTE(k); j++)
     29 				data->distr[(t & (m << (j*k))) >> (j*k)]++;
     30 		}
     31 		t = table[(line+1) * H48_LINE_BYTES - 1];
     32 		data->distr[(t & (m << (2*k))) >> (2*k)]--;
     33 		data->distr[(t & (m << (3*k))) >> (3*k)]--;
     34 	}
     35 
     36 	return NULL;
     37 }
     38 
     39 STATIC void
     40 getdistribution_h48(
     41 	const unsigned char *table,
     42 	uint64_t distr[static INFO_DISTRIBUTION_LEN],
     43 	const tableinfo_t info[static 1]
     44 ) {
     45 	getdistribution_data_t targ[THREADS];
     46 	wrapthread_define_var_thread_t(thread[THREADS]);
     47 	uint64_t local_distr[THREADS][INFO_DISTRIBUTION_LEN];
     48 	uint64_t i, j, lines, lines_per_thread, c;
     49 
     50 	lines = H48_LINES(info->h48h);
     51 	lines_per_thread = DIV_ROUND_UP(lines, THREADS);
     52 
     53 	for (i = 0; i < THREADS; i++) {
     54 		targ[i] = (getdistribution_data_t) {
     55 			.min = i * lines_per_thread,
     56 			.max = MIN((i+1) * lines_per_thread, lines),
     57 			.bits = info->bits,
     58 			.distr = local_distr[i],
     59 			.table = table,
     60 		};
     61 		wrapthread_create(&thread[i], NULL,
     62 		    getdistribution_h48_runthread, &targ[i]);
     63 	}
     64 
     65 	for (i = 0; i < THREADS; i++)
     66 		wrapthread_join(thread[i], NULL);
     67 
     68 	memset(distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t));
     69 	for (i = 0; i < THREADS; i++)
     70 		for (j = 0; j < INFO_DISTRIBUTION_LEN; j++)
     71 			distr[j] += local_distr[i][j];
     72 
     73 	/* Clean up excess values */
     74 	c = H48_LINE_EXT(H48_COORDMAX(info->h48h)) % H48_LINE_ALLCOORDS;
     75 	distr[3] -= H48_LINE_COORDS - c;
     76 }