aboutsummaryrefslogtreecommitdiff
path: root/src/solvers/distribution.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/solvers/distribution.h')
-rw-r--r--src/solvers/distribution.h77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/solvers/distribution.h b/src/solvers/distribution.h
new file mode 100644
index 0000000..1a3719c
--- /dev/null
+++ b/src/solvers/distribution.h
@@ -0,0 +1,77 @@
1#define ENTRIES_PER_BYTE(k) (UINT64_C(8) / (uint64_t)(k))
2#define TABLE_SHIFT(i, k) ((uint8_t)(k) * (uint8_t)((i) % ENTRIES_PER_BYTE(k)))
3#define TABLE_MASK(i, k) ((UINT8_BIT(k) - UINT8_C(1)) << TABLE_SHIFT(i, k))
4
5typedef struct {
6 uint64_t min;
7 uint64_t max;
8 uint8_t bits;
9 uint64_t *distr;
10 const unsigned char *table;
11} getdistribution_data_t;
12
13STATIC void *getdistribution_runthread(void *);
14STATIC void getdistribution(const unsigned char *,
15 uint64_t [static INFO_DISTRIBUTION_LEN], const tableinfo_t [static 1]);
16
17STATIC void *
18getdistribution_runthread(void *arg)
19{
20 getdistribution_data_t *data = (getdistribution_data_t *)arg;
21 const unsigned char *table;
22 uint8_t j, k, m;
23 uint64_t i;
24
25 memset(data->distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t));
26
27 k = data->bits;
28 table = data->table;
29 m = TABLE_MASK(0, k);
30 for (i = data->min; i < data->max; i++)
31 for (j = 0; j < ENTRIES_PER_BYTE(k); j++)
32 data->distr[(table[i] & (m << (j*k))) >> (j*k)]++;
33
34 return NULL;
35}
36
37STATIC void
38getdistribution(
39 const unsigned char *table,
40 uint64_t distr[static INFO_DISTRIBUTION_LEN],
41 const tableinfo_t info[static 1]
42) {
43 getdistribution_data_t targ[THREADS];
44 pthread_t thread[THREADS];
45 uint8_t pval, k;
46 uint64_t local_distr[THREADS][INFO_DISTRIBUTION_LEN];
47 uint64_t i, j, nbytes, sz, epb;
48
49 k = info->bits;
50 epb = ENTRIES_PER_BYTE(k);
51 nbytes = info->entries / epb;
52 sz = nbytes / THREADS;
53 for (i = 0; i < THREADS; i++) {
54 targ[i] = (getdistribution_data_t) {
55 .min = i * sz,
56 .max = i == THREADS - 1 ? nbytes : (i+1) * sz,
57 .bits = k,
58 .distr = local_distr[i],
59 .table = table,
60 };
61 pthread_create(&thread[i], NULL,
62 getdistribution_runthread, &targ[i]);
63 }
64
65 for (i = 0; i < THREADS; i++)
66 pthread_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 for (i = nbytes * epb; i < info->entries; i++) {
74 pval = (table[i/epb] & TABLE_MASK(i, k)) >> TABLE_SHIFT(i, k);
75 distr[pval]++;
76 }
77}

Generated with cgit - Back to sebastiano.tronto.net