/* * Straightforward Sieve of Eratosthenes, but skipping 3. * * Uses 1 bit per odd number. * * Time for Pi(10^10) = 48.5s */ static WTYPE* sieve_base23(WTYPE end) { WTYPE* mem; size_t n, s; size_t last = (end+1)/2; mem = (WTYPE*) calloc( NWORDS(last), sizeof(WTYPE) ); assert(mem != 0); SET_ARRAY_BIT(mem, 1/2); /* 1 is composite */ /* Mark all multiples of 3. Could skip if callers know this. */ for (n = 3*3; n <= end; n += 2*3) SET_ARRAY_BIT(mem,n/2); n = 5; while ( (n*n) <= end ) { if (!IS_SET_ARRAY_BIT(mem,n/2)) { for (s = n*n; s <= end; s += 2*n) { SET_ARRAY_BIT(mem,s/2); } } n += 2; if ( ((n*n) <= end) && (!IS_SET_ARRAY_BIT(mem,n/2)) ) { for (s = n*n; s <= end; s += 2*n) { SET_ARRAY_BIT(mem,s/2); } } n += 4; } return mem; }
static tracer_cmdresp_t _event_op_set_all(tracer_event_state_t state) { int ii; int saveBit; saveBit = GET_ARRAY_BIT(event_op_ctrl_t, tracer_config.event_op_ctrl, TRACER_EVENT_RESERVE_0); if (TRACER_EVENT_ON == state) { if ((TRACER_EVENT_ID_MAX - 1) != tracer_config.event_in_use_count) { memset (tracer_config.event_op_ctrl, 0xFF, TRACER_EVENT_ID_MAX >> 3); for (ii = (TRACER_EVENT_ID_MAX & (~(uint32)0x07)); ii < TRACER_EVENT_ID_MAX; ii++) { SET_ARRAY_BIT(event_op_ctrl_t, tracer_config.event_op_ctrl, ii); } if (0 == saveBit) { CLR_ARRAY_BIT(event_op_ctrl_t, tracer_config.event_op_ctrl, TRACER_EVENT_RESERVE_0); } tracer_config.event_in_use_count = TRACER_EVENT_ID_MAX - 1; // less RESERVE0 event return TRACER_CMDRESP_SUCCESS; } }
// Dependency: bTracerInitialized is TRUE. static tracer_cmdresp_t _entity_op_set(tracer_ost_entity_id_enum_t eid, tracer_entity_state_t state) { if (TRACER_ENTITY_SWEVT == eid) { return TRACER_CMDRESP_F_INVALID; } if (((0 == state) ? TRACER_ENTITY_OFF : TRACER_ENTITY_ON) != GET_ARRAY_BIT(entity_op_ctrl_t, tracer_config.entity_op_ctrl, eid)) { if (TRACER_ENTITY_ON == state) { SET_ARRAY_BIT(entity_op_ctrl_t, tracer_config.entity_op_ctrl, eid); tracer_config.entity_in_use_count++; } else { CLR_ARRAY_BIT(entity_op_ctrl_t, tracer_config.entity_op_ctrl, eid); tracer_config.entity_in_use_count--; } return TRACER_CMDRESP_SUCCESS; } return TRACER_CMDRESP_S_UNCHANGED; }
// Dependency: bTracerInitialized is TRUE. static tracer_cmdresp_t _entity_op_set_all(tracer_entity_state_t state) { tracer_cmdresp_t ret_val; int ii; ret_val = TRACER_CMDRESP_S_UNCHANGED; for (ii = 0; ii < TRACER_NUM_USER_ENTITIES; ii++) { if (TRACER_ENTITY_SWEVT != tracer_entity_vals[ii]) { if (((0 == state) ? TRACER_ENTITY_OFF : TRACER_ENTITY_ON) != GET_ARRAY_BIT(entity_op_ctrl_t, tracer_config.entity_op_ctrl, tracer_entity_vals[ii])) { if (TRACER_ENTITY_ON == state) { SET_ARRAY_BIT(entity_op_ctrl_t, tracer_config.entity_op_ctrl, tracer_entity_vals[ii]); tracer_config.entity_in_use_count++; } else { CLR_ARRAY_BIT(entity_op_ctrl_t, tracer_config.entity_op_ctrl, tracer_entity_vals[ii]); tracer_config.entity_in_use_count--; } ret_val = TRACER_CMDRESP_SUCCESS; } } } return ret_val; }
/* * Naive Wheel factoring based on algorithm Ek from Sorenson 1991 * * Uses 1 bit per odd number. * * Note we're including initialization code that marks all 3,5 multiples. * If the caller didn't look at these, this could be skipped. * * Time for Pi(10^10) = 46.4s */ static WTYPE* sieve_eratek(WTYPE end) { WTYPE* mem; size_t p, f, x; size_t last = (end+1)/2; static const WTYPE wheel[] = {1, 7, 11, 13, 17, 19, 23, 29}; static const WTYPE W[] = {0,6,0,0,0,0,0,4,0,0,0,2,0,4,0,0,0,2,0,4,0,0,0,6,0,0,0,0,0,2,0}; mem = (WTYPE*) calloc( NWORDS(last), sizeof(WTYPE) ); assert(mem != 0); /* Mark all multiples of 3 and 5 as composite. */ //for (p = 3*3; p <= end; p += 2*3) SET_ARRAY_BIT(mem,p/2); //for (p = 5*5; p <= end; p += 2*5) SET_ARRAY_BIT(mem,p/2); p = 9; while (p <= end) { SET_ARRAY_BIT(mem,p/2); p += 6; if (p > end) break; // mark 9, p = 15 SET_ARRAY_BIT(mem,p/2); p += 6; if (p > end) break; // mark 15, p = 21 SET_ARRAY_BIT(mem,p/2); p += 4; if (p > end) break; // mark 21, p = 25 SET_ARRAY_BIT(mem,p/2); p += 2; if (p > end) break; // mark 25, p = 27 SET_ARRAY_BIT(mem,p/2); p += 6; if (p > end) break; // mark 27, p = 33 SET_ARRAY_BIT(mem,p/2); p += 2; if (p > end) break; // mark 33, p = 35 SET_ARRAY_BIT(mem,p/2); p += 4; // mark 35, p = 39 } p = 7; while ((p*p) <= end) { { size_t fidx = p%30; f = p; /* Here's the problem -- for each prime, we're walking the array from * start to finish 8 times. The operation count is the same as the * faster wheel-30 sieves, but this is just horrible for the cache. */ while (f < p+30) { for (x = p*f; x <= end; x += p*30) SET_ARRAY_BIT(mem,x/2); size_t move = W[fidx]; f += move; fidx += move; if (fidx > 30) fidx -= 30; } } //p = next_prime(p); do { p += 2; } while (IS_SET_ARRAY_BIT(mem,p/2)); } SET_ARRAY_BIT(mem, 1/2); /* 1 is composite */ CLR_ARRAY_BIT(mem, 3/2); /* 3 is prime */ CLR_ARRAY_BIT(mem, 5/2); /* 5 is prime */ return mem; }
/* * Better Sieve of Atkin. * * Uses 1 bit per odd number. * * Just some simple optimizations to make it a little better. Still not good. * * Time for Pi(10^10) = 97.2s */ static WTYPE* sieve_atkin_2(WTYPE end) { WTYPE* mem; size_t x, y, n, sqlimit; size_t last = (end+1+1)/2; long loopend, y_limit, dn; end++; mem = (WTYPE*) malloc( NWORDS(last) * sizeof(WTYPE) ); assert(mem != 0); /* mark everything as a composite */ memset(mem, 0xFF, NBYTES(last)); sqlimit = sqrtf(end); for (x = 1; x <= sqlimit; x++) { { size_t xx4 = 4*x*x; y = 1; for (n = xx4+1; n <= end; n = xx4+y*y) { size_t nmod12 = n%12; if ( (nmod12 == 1) || (nmod12 == 5) ) XOR_ARRAY_BIT(mem,n/2); y++; } } { size_t xx3 = 3*x*x; y = 1; for (n = xx3+1; n <= end; n = xx3+y*y) { size_t nmod12 = n%12; if (nmod12 == 7) XOR_ARRAY_BIT(mem,n/2); y++; } y = x-1; while ( y*y >= xx3 ) y--; for (n = xx3-y*y; y >= 1 && n <= end; n = xx3-y*y) { size_t nmod12 = n%12; if (nmod12 == 11) XOR_ARRAY_BIT(mem,n/2); y--; } } } /* Mark all squares of primes as composite */ for (n = 5; n <= sqlimit; n += 2) if (!IS_SET_ARRAY_BIT(mem,n/2)) for (y = n*n; y <= end; y += 2*n*n) SET_ARRAY_BIT(mem,y/2); CLR_ARRAY_BIT(mem, 3/2); /* 3 is prime */ return mem; }
/* * Straightforward Sieve of Eratosthenes. * * Uses 1 bit per odd number. * * Time for Pi(10^10) = 54.6s */ static WTYPE* sieve_erat(WTYPE end) { WTYPE* mem; size_t n, s; size_t last = (end+1)/2; mem = (WTYPE*) calloc( NWORDS(last), sizeof(WTYPE) ); assert(mem != 0); // Tight: // for (n = 3; (n*n) <= end; n = next_prime(n)) // for (s = n*n; s <= end; s += 2*n) // SET_ARRAY_BIT(mem,s/2); n = 3; while ( (n*n) <= end) { for (s = n*n; s <= end; s += 2*n) SET_ARRAY_BIT(mem,s/2); // Could do: n = next_prime(n) do { n += 2; } while (IS_SET_ARRAY_BIT(mem,n/2)); } SET_ARRAY_BIT(mem, 1/2); /* 1 is composite */ return mem; }
/* * Naive Sieve of Atkin. * * Uses 1 bit per odd number. * * This is really slow. Just keeping it here as a reference. * * Time for Pi(10^10) = 123.5s */ static WTYPE* sieve_atkin_naive(WTYPE end) { WTYPE* mem; size_t x, y, n, sqlimit; size_t last = (end+1+1)/2; long loopend, y_limit, dn; end++; mem = (WTYPE*) malloc( NWORDS(last) * sizeof(WTYPE) ); assert(mem != 0); /* mark everything as a composite */ memset(mem, 0xFF, NBYTES(last)); sqlimit = sqrt(end); for (x = 1; x <= sqlimit; x++) { for (y = 1; y <= sqlimit; y++) { n = 4*x*x + y*y; if ( (n <= end) && (n % 12 == 1 || n % 12 == 5) ) XOR_ARRAY_BIT(mem,n/2); n = 3*x*x + y*y; if ( (n <= end) && (n % 12 == 7) ) XOR_ARRAY_BIT(mem,n/2); n = 3*x*x - y*y; if ( (n <= end) && (x > y) && (n % 12 == 11) ) XOR_ARRAY_BIT(mem,n/2); } } /* Mark all squares of primes as composite */ for (n = 5; n <= sqlimit; n += 2) if (!IS_SET_ARRAY_BIT(mem,n/2)) for (y = n*n; y <= end; y += 2*n*n) SET_ARRAY_BIT(mem,y/2); CLR_ARRAY_BIT(mem, 3/2); /* 3 is prime */ return mem; }