/* primes below N. the same loops as tests/bench/sieve.zc. word: one int64 flag per number (what zc's fast path can do). byte: one byte per number, the representation a C sieve would actually use. the count is 9592 either way. usage: sieve word|byte REPS */ #include #include #include enum { N = 100000, EXPECT = 9592 }; static int sieve_word(int64_t *restrict f) { int c = 0; for (int i = 2; i < N; i++) f[i] = 1; for (int i = 2; (long long)i * i < N; i++) if (f[i]) for (int j = i * i; j < N; j += i) f[j] = 0; for (int i = 2; i < N; i++) c += (int)f[i]; return c; } static int sieve_byte(unsigned char *restrict f) { int c = 0; for (int i = 2; i < N; i++) f[i] = 1; for (int i = 2; (long long)i * i < N; i++) if (f[i]) for (int j = i * i; j < N; j += i) f[j] = 0; for (int i = 2; i < N; i++) c += f[i]; return c; } int main(int argc, char **argv) { int reps, r = 0, k, byte; int64_t *w = 0; unsigned char *b = 0; if (argc != 3) return 2; byte = argv[1][0] == 'b'; reps = atoi(argv[2]); if (byte) b = malloc(N); else w = malloc((size_t)N * sizeof *w); if (!w && !b) return 3; for (k = 0; k < reps; k++) { r = byte ? sieve_byte(b) : sieve_word(w); /* the stores have to happen: the next pass must see a clobbered buffer */ __asm__ __volatile__("" : "+r"(r) : "r"(byte ? (void *)b : (void *)w) : "memory"); } if (r != EXPECT) { fprintf(stderr, "bad %d\n", r); return 1; } printf("%d\n", r); free(w); free(b); return 0; }