cae7291

primebnc -- prime generation benchmark

Sep 19th, 2016
261
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.75 KB | None | 0 0
  1. // primebnc/primebnc -- prime algorithm benchmark
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <time.h>
  6.  
  7. //#define MAXCNT 10001
  8. //#define MAXCNT 20002
  9. //#define MAXCNT 30003
  10. //#define MAXCNT 40004
  11. #define MAXCNT 1000000
  12.  
  13. int opt_f;
  14.  
  15. typedef unsigned long long val_t;
  16.  
  17. int tstno;
  18. int inited;
  19. char *reason;
  20.  
  21. int pcntold;
  22. double bestrate;
  23. double tvprev;
  24.  
  25. int maxcnt;
  26. val_t pxold[MAXCNT + 1];
  27. val_t pxnow[MAXCNT + 1];
  28.  
  29. int
  30. prime1(val_t *primes)
  31. {
  32. val_t i;
  33. int idx;
  34. int isprime;
  35. val_t n = 2;
  36.  
  37. idx = 0;
  38. while (idx <= maxcnt) {
  39. isprime = 1;
  40. for (i = 2; i < n; i++) {
  41. if (n % i == 0) {
  42. isprime = 0;
  43. break;
  44. }
  45. }
  46.  
  47. if (isprime) {
  48. primes[idx] = n;
  49. idx++;
  50. }
  51.  
  52. n++;
  53. }
  54.  
  55. tstno = 1;
  56. reason = "baseline 2 to n";
  57.  
  58. return idx;
  59. }
  60.  
  61. int
  62. prime2(val_t *primes)
  63. {
  64. val_t i;
  65. int idx;
  66. int isprime;
  67. val_t xsqrt;
  68. val_t n = 2;
  69. val_t n2;
  70.  
  71. xsqrt = 0;
  72.  
  73. idx = 0;
  74. primes[idx++] = 2;
  75.  
  76. while (idx <= maxcnt) {
  77. // get sqrt(n)
  78. while ((xsqrt * xsqrt) < n) {
  79. xsqrt += 1;
  80. }
  81.  
  82. isprime = 1;
  83. for (i = 2; i <= xsqrt; i++) {
  84. if (n % i == 0) {
  85. isprime = 0;
  86. break;
  87. }
  88. }
  89.  
  90. if (isprime) {
  91. primes[idx] = n;
  92. idx++;
  93. }
  94.  
  95. n2 = n + 1;
  96. if (n2 < n)
  97. printf("overflow: idx=%d\n",idx);
  98. n = n2;
  99. }
  100.  
  101. tstno = 2;
  102. reason = "2 to sqrt by 2";
  103.  
  104. return idx;
  105. }
  106.  
  107. int
  108. prime3(val_t *primes)
  109. {
  110. val_t i;
  111. int idx;
  112. int isprime;
  113. val_t xsqrt;
  114. val_t n;
  115.  
  116. xsqrt = 0;
  117.  
  118. idx = 0;
  119. primes[idx++] = 2;
  120. primes[idx++] = 3;
  121. n = 5;
  122.  
  123. while (idx <= maxcnt) {
  124. // get sqrt(n)
  125. while ((xsqrt * xsqrt) < n) {
  126. xsqrt += 1;
  127. }
  128.  
  129. isprime = 1;
  130. for (i = 3; i <= xsqrt; i += 2) {
  131. if (n % i == 0) {
  132. isprime = 0;
  133. break;
  134. }
  135. }
  136.  
  137. if (isprime) {
  138. primes[idx] = n;
  139. idx++;
  140. }
  141.  
  142. n += 2;
  143. }
  144.  
  145. tstno = 3;
  146. reason = "3 to sqrt by 2";
  147.  
  148. return idx;
  149. }
  150.  
  151. int
  152. prime4(val_t *primes)
  153. {
  154. val_t i;
  155. int idx;
  156. int isprime;
  157. val_t xsqrt;
  158. val_t n;
  159. val_t lo;
  160. val_t hi;
  161.  
  162. xsqrt = 0;
  163.  
  164. idx = 0;
  165. primes[idx++] = 2;
  166. primes[idx++] = 3;
  167. n = 6;
  168.  
  169. while (idx <= maxcnt) {
  170. lo = n - 1;
  171. hi = n + 1;
  172.  
  173. // get sqrt(n)
  174. while ((xsqrt * xsqrt) < hi) {
  175. xsqrt += 1;
  176. }
  177.  
  178. isprime = 3;
  179. for (i = 3; i <= xsqrt; i += 2) {
  180. if (isprime & 1) {
  181. if (lo % i == 0)
  182. isprime &= ~1;
  183. }
  184. if (isprime & 2) {
  185. if (hi % i == 0)
  186. isprime &= ~2;
  187. }
  188. if (! isprime)
  189. break;
  190. }
  191.  
  192. if (isprime & 1) {
  193. primes[idx] = lo;
  194. idx++;
  195. }
  196.  
  197. if (isprime & 2) {
  198. primes[idx] = hi;
  199. idx++;
  200. }
  201.  
  202. n += 6;
  203. }
  204.  
  205. tstno = 4;
  206. reason = "6 to sqrt by 6 (combined 6n-1/6n+1 loops)";
  207.  
  208. return idx;
  209. }
  210.  
  211. int
  212. prime5(val_t *primes)
  213. {
  214. val_t i;
  215. int idx;
  216. int isprime;
  217. val_t xsqrt;
  218. val_t n;
  219. val_t lo;
  220. val_t hi;
  221.  
  222. xsqrt = 0;
  223.  
  224. idx = 0;
  225. primes[idx++] = 2;
  226. primes[idx++] = 3;
  227. n = 6;
  228.  
  229. while (idx <= maxcnt) {
  230. lo = n - 1;
  231. hi = n + 1;
  232.  
  233. // get sqrt(n)
  234. while ((xsqrt * xsqrt) < hi) {
  235. xsqrt += 1;
  236. }
  237.  
  238. isprime = 1;
  239. for (i = 3; i <= xsqrt; i += 2) {
  240. if (lo % i == 0) {
  241. isprime = 0;
  242. break;
  243. }
  244. }
  245. if (isprime) {
  246. primes[idx] = lo;
  247. idx++;
  248. }
  249.  
  250. isprime = 1;
  251. for (i = 3; i <= xsqrt; i += 2) {
  252. if (hi % i == 0) {
  253. isprime = 0;
  254. break;
  255. }
  256. }
  257. if (isprime) {
  258. primes[idx] = hi;
  259. idx++;
  260. }
  261.  
  262. n += 6;
  263. }
  264.  
  265. tstno = 5;
  266. reason = "6 to sqrt by 6 (separate 6n-1/6n+1 loops)";
  267.  
  268. return idx;
  269. }
  270.  
  271. int
  272. prime6(val_t *primes)
  273. {
  274. int cnt;
  275. int isprime;
  276. val_t xsqrt;
  277. val_t n;
  278. val_t lo;
  279. val_t hi;
  280. val_t pval;
  281. val_t *pptr;
  282. val_t *pend;
  283.  
  284. xsqrt = 0;
  285.  
  286. cnt = 0;
  287. primes[cnt++] = 2;
  288. primes[cnt++] = 3;
  289. n = 6;
  290.  
  291. while (cnt <= maxcnt) {
  292. lo = n - 1;
  293. hi = n + 1;
  294.  
  295. // get sqrt(n)
  296. while ((xsqrt * xsqrt) < hi) {
  297. xsqrt += 1;
  298. }
  299.  
  300. isprime = 3;
  301. pptr = primes;
  302. pend = primes + cnt;
  303. for (; pptr < pend; ++pptr) {
  304. pval = *pptr;
  305.  
  306. // early stop if we exceed square root of number being tested
  307. if (pval > xsqrt)
  308. break;
  309.  
  310. // test 6n - 1
  311. if (isprime & 1) {
  312. if ((lo % pval) == 0)
  313. isprime &= ~1;
  314. }
  315.  
  316. // test 6n + 1
  317. if (isprime & 2) {
  318. if ((hi % pval) == 0)
  319. isprime &= ~2;
  320. }
  321.  
  322. // bug out if both are non-prime
  323. if (! isprime)
  324. break;
  325. }
  326.  
  327. // 6n - 1 is prime
  328. if (isprime & 1) {
  329. primes[cnt] = lo;
  330. cnt++;
  331. }
  332.  
  333. // 6n + 1 is prime
  334. if (isprime & 2) {
  335. primes[cnt] = hi;
  336. cnt++;
  337. }
  338.  
  339. n += 6;
  340. }
  341.  
  342. tstno = 6;
  343. reason = "6 to sqrt by prime list (combined 6n-1/6n+1 loops)";
  344.  
  345. return cnt;
  346. }
  347.  
  348. int
  349. prime7(val_t *primes)
  350. {
  351. int cnt;
  352. int isprime;
  353. val_t xsqrt;
  354. val_t n;
  355. val_t lo;
  356. val_t hi;
  357. val_t pval;
  358. val_t *pptr;
  359. val_t *pend;
  360.  
  361. xsqrt = 0;
  362.  
  363. cnt = 0;
  364. primes[cnt++] = 2;
  365. primes[cnt++] = 3;
  366. n = 6;
  367.  
  368. while (cnt <= maxcnt) {
  369. lo = n - 1;
  370. hi = n + 1;
  371.  
  372. // get sqrt(n)
  373. while ((xsqrt * xsqrt) < hi) {
  374. xsqrt += 1;
  375. }
  376.  
  377. // check for 6n - 1 is prime
  378. isprime = 1;
  379. pptr = primes;
  380. pend = primes + cnt;
  381. for (; pptr < pend; ++pptr) {
  382. pval = *pptr;
  383.  
  384. // early stop if we exceed square root of number being tested
  385. if (pval > xsqrt)
  386. break;
  387.  
  388. // test 6n - 1
  389. if ((lo % pval) == 0) {
  390. isprime = 0;
  391. break;
  392. }
  393. }
  394. if (isprime) {
  395. primes[cnt] = lo;
  396. cnt++;
  397. }
  398.  
  399. // check for 6n + 1 is prime
  400. isprime = 1;
  401. pptr = primes;
  402. pend = primes + cnt;
  403. for (; pptr < pend; ++pptr) {
  404. pval = *pptr;
  405.  
  406. // early stop if we exceed square root of number being tested
  407. if (pval > xsqrt)
  408. break;
  409.  
  410. // test 6n + 1
  411. if ((hi % pval) == 0) {
  412. isprime = 0;
  413. break;
  414. }
  415. }
  416. if (isprime) {
  417. primes[cnt] = hi;
  418. cnt++;
  419. }
  420.  
  421. n += 6;
  422. }
  423.  
  424. tstno = 7;
  425. reason = "6 to sqrt by prime list (separate 6n-1/6n+1 loops)";
  426.  
  427. return cnt;
  428. }
  429.  
  430. double
  431. tvgetf(void)
  432. {
  433. struct timespec ts;
  434. double sec;
  435.  
  436. clock_gettime(CLOCK_REALTIME,&ts);
  437.  
  438. sec = ts.tv_nsec;
  439. sec /= 1e9;
  440. sec += ts.tv_sec;
  441.  
  442. return sec;
  443. }
  444.  
  445. void
  446. timeit(int (*p)(val_t *))
  447. {
  448. val_t *pnow;
  449. val_t *pold;
  450. int pcntact;
  451. double tvbeg;
  452. double tvend;
  453. double rate;
  454. double ratio;
  455.  
  456. printf("---------------\n");
  457.  
  458. pold = pxold;
  459. pnow = inited ? pxnow : pxold;
  460.  
  461. // load up the cache
  462. for (int i = 0; i < maxcnt; i++)
  463. pnow[i] = 1;
  464.  
  465. tvbeg = tvgetf();
  466. pcntact = p(pnow);
  467. tvend = tvgetf();
  468.  
  469. tvend -= tvbeg;
  470.  
  471. // show prime generation rate
  472. rate = (double) maxcnt / tvend;
  473. printf("prime%d: %.9f (%.3f primes/sec",tstno,tvend,rate);
  474. if (inited) {
  475. ratio = rate / bestrate;
  476. printf(" %.3fx %s",ratio,(ratio > 1.0) ? "faster" : "slower");
  477. }
  478. printf(")");
  479.  
  480. do {
  481. if (! inited) {
  482. pcntold = pcntact;
  483. bestrate = rate;
  484. printf(" -- %s\n",reason);
  485. break;
  486. }
  487.  
  488. // show time ratio
  489. ratio = tvprev / tvend;
  490. printf(" %.3fx (%s than previous)",
  491. ratio,(ratio > 1.0) ? "faster" : "slower");
  492.  
  493. printf(" -- %s\n",reason);
  494.  
  495. for (int i = 0; i < maxcnt; i++) {
  496. if (pnow[i] != pold[i]) {
  497. printf("%d: pold=%lld pnow=%lld\n",i,pold[i],pnow[i]);
  498. break;
  499. }
  500. }
  501. } while (0);
  502.  
  503. tvprev = tvend;
  504. inited = 1;
  505. }
  506.  
  507. int
  508. main(int argc,char **argv)
  509. {
  510. char *cp;
  511.  
  512. --argc;
  513. ++argv;
  514.  
  515. maxcnt = MAXCNT;
  516.  
  517. for (; argc > 0; --argc, ++argv) {
  518. cp = *argv;
  519. if (*cp != '-')
  520. break;
  521.  
  522. switch (cp[1]) {
  523. case 'f':
  524. opt_f = 1;
  525. break;
  526. case 'N':
  527. maxcnt = strtol(cp + 2,&cp,10);
  528. break;
  529. }
  530. }
  531.  
  532. if (opt_f)
  533. maxcnt = 40004;
  534.  
  535. if (maxcnt > MAXCNT)
  536. maxcnt = MAXCNT;
  537.  
  538. // this takes a whole minute
  539. if (opt_f)
  540. timeit(prime1);
  541.  
  542. // these are _much_ faster
  543. timeit(prime2);
  544. timeit(prime3);
  545. timeit(prime4);
  546. timeit(prime5);
  547. timeit(prime6);
  548. timeit(prime7);
  549.  
  550. #if 0
  551. for (int i = 0; i < maxcnt; i++) {
  552. printf("%d\n", pxold[i]);
  553. }
  554. #endif
  555.  
  556. return 0;
  557. }
Advertisement
Add Comment
Please, Sign In to add comment