reuse range generation from ↕n for •rand.Deal
This commit is contained in:
parent
1072d0bb9c
commit
65d0b829bd
@ -7,23 +7,18 @@
|
||||
#include "../nfns.h"
|
||||
|
||||
|
||||
|
||||
NOINLINE B intRange(ux s, ux n) { // intended for s+n≥128; assumes n≥1
|
||||
assert(n>0);
|
||||
ux last = n+s-1;
|
||||
if (last<=I16_MAX) {
|
||||
i16* rp; B r = m_i16arrv(&rp, n);
|
||||
for (ux i = 0; i < n; i++) rp[i] = (i16)s + (i16)i;
|
||||
return r;
|
||||
}
|
||||
if (last<=I32_MAX) {
|
||||
i32* rp; B r = m_i32arrv(&rp, n);
|
||||
for (ux i = 0; i < n; i++) rp[i] = (i32)s + (i32)i;
|
||||
return r;
|
||||
}
|
||||
|
||||
NOINLINE B intRange16(ux s, ux n) { // s+↕n with i16arr result
|
||||
i16* rp; B r = m_i16arrv(&rp, n);
|
||||
for (ux i = 0; i < n; i++) rp[i] = (i16)s + (i16)i;
|
||||
return r;
|
||||
}
|
||||
NOINLINE B intRange32(ux s, ux n) { // s+↕n with i32arr result
|
||||
i32* rp; B r = m_i32arrv(&rp, n);
|
||||
for (ux i = 0; i < n; i++) rp[i] = (i32)s + (i32)i;
|
||||
return r;
|
||||
}
|
||||
NOINLINE B intRangeF64(ux s, ux n) { // s+↕n with f64arr result
|
||||
f64* rp; B r = m_f64arrv(&rp, n);
|
||||
|
||||
f64 c = s;
|
||||
PLAINLOOP for (ux i = 0; i < n/16; i++) {
|
||||
for (ux j = 0; j < 16; j++) rp[j] = c+j;
|
||||
@ -33,6 +28,13 @@ NOINLINE B intRange(ux s, ux n) { // intended for s+n≥128; assumes n≥1
|
||||
for (ux j = 0; j < (n&15); j++) rp[j] = c+j;
|
||||
return r;
|
||||
}
|
||||
B intRange(ux s, ux n) { // intended for s+n≥128; assumes n≥1
|
||||
assert(n>0);
|
||||
ux last = n+s-1;
|
||||
if (last<=I16_MAX) return intRange16(s, n);
|
||||
if (last<=I32_MAX) return intRange32(s, n);
|
||||
return intRangeF64(s, n);
|
||||
}
|
||||
|
||||
static B* ud_rec(B* p, usz d, usz r, i32* pos, usz* sh) {
|
||||
usz cl = sh[d];
|
||||
|
||||
@ -427,6 +427,9 @@ B rand_range_c2(B t, B w, B x) {
|
||||
|
||||
extern Arr* bitUD[3]; // from fns.c
|
||||
extern B bit2x[2];
|
||||
NOINLINE B intRange16(ux s, ux n);
|
||||
NOINLINE B intRange32(ux s, ux n);
|
||||
|
||||
B rand_deal_c1(B t, B x) {
|
||||
i32 xi = o2i(x);
|
||||
if (RARE(xi<=1)) {
|
||||
@ -437,7 +440,6 @@ B rand_deal_c1(B t, B x) {
|
||||
RAND_START;
|
||||
B r;
|
||||
#define SHUF \
|
||||
for (usz i = 0; i < xi; i++) rp[i] = i; \
|
||||
for (usz i = 0; i < xi-1; i++) { \
|
||||
usz j = wy2u0k(wyrand(&seed), xi-i) + i; \
|
||||
usz c=rp[j]; rp[j]=rp[i]; rp[i]=c; \
|
||||
@ -446,15 +448,17 @@ B rand_deal_c1(B t, B x) {
|
||||
r = incG(bit2x[wyrand(&seed)&1]);
|
||||
} else if (LIKELY(xi <= 128)) {
|
||||
i8* rp; r = m_i8arrv(&rp, xi);
|
||||
NOUNROLL for (usz i = 0; i < xi; i++) rp[i] = i;
|
||||
SHUF
|
||||
} else if (LIKELY(xi <= 1<<15)) {
|
||||
i16* rp; r = m_i16arrv(&rp, xi);
|
||||
r = intRange16(0, xi); i16* rp = i16arr_ptr(r);
|
||||
SHUF
|
||||
} else {
|
||||
i32* rp; r = m_i32arrv(&rp, xi);
|
||||
if (xi <= 1<<19) {
|
||||
r = intRange32(0, xi); i32* rp = i32arr_ptr(r);
|
||||
SHUF
|
||||
} else {
|
||||
i32* rp; r = m_i32arrv(&rp, xi);
|
||||
// Initial split pass like a random radix sort
|
||||
// Don't count partition size exactly; instead, assume lengths
|
||||
// are within 1 and stop when a partition is full
|
||||
|
||||
Loading…
Reference in New Issue
Block a user