void *generate_chase(const struct generate_chase_common_args *args, size_t mixer_idx) { char *arena = args->arena; size_t total_memory = args->total_memory; size_t stride = args->stride; size_t tlb_locality = args->tlb_locality; void (*gen_permutation)(perm_t *, size_t, size_t) = args->gen_permutation; const perm_t *mixer = args->mixer + mixer_idx * NR_MIXERS; size_t nr_mixer_indices = args->nr_mixer_indices; size_t nr_tlb_groups = total_memory / tlb_locality; size_t nr_elts_per_tlb = tlb_locality / stride; size_t nr_elts = total_memory / stride; perm_t *tlb_perm; perm_t *perm; size_t i; perm_t *perm_inverse; size_t mixer_scale = stride / nr_mixer_indices; if (verbosity > 1) printf("generating permutation of %zu elements (in %zu TLB groups)\n", nr_elts, nr_tlb_groups); tlb_perm = malloc(nr_tlb_groups * sizeof(*tlb_perm)); gen_permutation(tlb_perm, nr_tlb_groups, 0); perm = malloc(nr_elts * sizeof(*perm)); for (i = 0; i < nr_tlb_groups; ++i) { gen_permutation(&perm[i * nr_elts_per_tlb], nr_elts_per_tlb, tlb_perm[i] * nr_elts_per_tlb); } free(tlb_perm); dassert(is_a_permutation(perm, nr_elts)); if (verbosity > 1) printf("generating inverse permtuation\n"); perm_inverse = malloc(nr_elts * sizeof(*perm)); for (i = 0; i < nr_elts; ++i) { perm_inverse[perm[i]] = i; } dassert(is_a_permutation(perm_inverse, nr_elts)); #define MIXED(x) \ ((x)*stride + mixer[(x) & (NR_MIXERS-1)]*mixer_scale) if (verbosity > 1) printf("threading the chase (mixer_idx = %zu)\n", mixer_idx); for (i = 0; i < nr_elts; ++i) { size_t next; dassert(perm[perm_inverse[i]] == i); assert(*(void **)(arena + MIXED(i)) == NULL); next = perm_inverse[i] + 1; next = (next == nr_elts) ? 0 : next; *(void **)(arena + MIXED(i)) = (void *)(arena + MIXED(perm[next])); } free(perm); free(perm_inverse); return arena + MIXED(0); }
// guarda permutación perm de tamaño sz, del conjunto charset, en array void save_perm(DynArray<string> & array, const string & perm, char * charset, const size_t & sz) { const size_t array_size = array.size(); if (array_size > 0) { int i = binary_search(array, perm); // verifica si la // permutación no ha sido // generada previamente if (array.access(i) == perm) return; // la permutación ya fue generada (hay símbolos repetidos) } if (is_a_permutation(perm, charset, sz)) array[array_size] = perm; }