diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-05-18 08:48:13 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-05-18 08:48:13 +0200 |
| commit | 8b94d135429a9f3253cc7f25a1453b412065c4a0 (patch) | |
| tree | 4a31d6def5421e95fb98505a2bc2653c18fca330 /src/solvers/distribution.h | |
| parent | 30b43f08955158d4f2066f4b50fe8d1241b3177b (diff) | |
| download | nissy-core-8b94d135429a9f3253cc7f25a1453b412065c4a0.tar.gz nissy-core-8b94d135429a9f3253cc7f25a1453b412065c4a0.zip | |
Refactor solver dispatch and checkdata
Diffstat (limited to 'src/solvers/distribution.h')
| -rw-r--r-- | src/solvers/distribution.h | 77 |
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 | |||
| 5 | typedef 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 | |||
| 13 | STATIC void *getdistribution_runthread(void *); | ||
| 14 | STATIC void getdistribution(const unsigned char *, | ||
| 15 | uint64_t [static INFO_DISTRIBUTION_LEN], const tableinfo_t [static 1]); | ||
| 16 | |||
| 17 | STATIC void * | ||
| 18 | getdistribution_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 | |||
| 37 | STATIC void | ||
| 38 | getdistribution( | ||
| 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 | } | ||
