17db96d56Sopenharmony_ci/* 27db96d56Sopenharmony_ci * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. 37db96d56Sopenharmony_ci * 47db96d56Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 57db96d56Sopenharmony_ci * modification, are permitted provided that the following conditions 67db96d56Sopenharmony_ci * are met: 77db96d56Sopenharmony_ci * 87db96d56Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 97db96d56Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 107db96d56Sopenharmony_ci * 117db96d56Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 127db96d56Sopenharmony_ci * notice, this list of conditions and the following disclaimer in the 137db96d56Sopenharmony_ci * documentation and/or other materials provided with the distribution. 147db96d56Sopenharmony_ci * 157db96d56Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND 167db96d56Sopenharmony_ci * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 177db96d56Sopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 187db96d56Sopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 197db96d56Sopenharmony_ci * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 207db96d56Sopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 217db96d56Sopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 227db96d56Sopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 237db96d56Sopenharmony_ci * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 247db96d56Sopenharmony_ci * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 257db96d56Sopenharmony_ci * SUCH DAMAGE. 267db96d56Sopenharmony_ci */ 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ci 297db96d56Sopenharmony_ci#include "mpdecimal.h" 307db96d56Sopenharmony_ci 317db96d56Sopenharmony_ci#include <stdint.h> 327db96d56Sopenharmony_ci#include <stdio.h> 337db96d56Sopenharmony_ci#include <stdlib.h> 347db96d56Sopenharmony_ci#include <time.h> 357db96d56Sopenharmony_ci 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_cistatic void 387db96d56Sopenharmony_cierr_exit(const char *msg) 397db96d56Sopenharmony_ci{ 407db96d56Sopenharmony_ci fprintf(stderr, "%s\n", msg); 417db96d56Sopenharmony_ci exit(1); 427db96d56Sopenharmony_ci} 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_cistatic mpd_t * 457db96d56Sopenharmony_cinew_mpd(void) 467db96d56Sopenharmony_ci{ 477db96d56Sopenharmony_ci mpd_t *x = mpd_qnew(); 487db96d56Sopenharmony_ci if (x == NULL) { 497db96d56Sopenharmony_ci err_exit("out of memory"); 507db96d56Sopenharmony_ci } 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ci return x; 537db96d56Sopenharmony_ci} 547db96d56Sopenharmony_ci 557db96d56Sopenharmony_ci/* 567db96d56Sopenharmony_ci * Example from: http://en.wikipedia.org/wiki/Mandelbrot_set 577db96d56Sopenharmony_ci * 587db96d56Sopenharmony_ci * Escape time algorithm for drawing the set: 597db96d56Sopenharmony_ci * 607db96d56Sopenharmony_ci * Point x0, y0 is deemed to be in the Mandelbrot set if the return 617db96d56Sopenharmony_ci * value is maxiter. Lower return values indicate how quickly points 627db96d56Sopenharmony_ci * escaped and can be used for coloring. 637db96d56Sopenharmony_ci */ 647db96d56Sopenharmony_cistatic int 657db96d56Sopenharmony_cicolor_point(const mpd_t *x0, const mpd_t *y0, const long maxiter, mpd_context_t *ctx) 667db96d56Sopenharmony_ci{ 677db96d56Sopenharmony_ci mpd_t *x, *y, *sq_x, *sq_y; 687db96d56Sopenharmony_ci mpd_t *two, *four, *c; 697db96d56Sopenharmony_ci long i; 707db96d56Sopenharmony_ci 717db96d56Sopenharmony_ci x = new_mpd(); 727db96d56Sopenharmony_ci y = new_mpd(); 737db96d56Sopenharmony_ci mpd_set_u32(x, 0, ctx); 747db96d56Sopenharmony_ci mpd_set_u32(y, 0, ctx); 757db96d56Sopenharmony_ci 767db96d56Sopenharmony_ci sq_x = new_mpd(); 777db96d56Sopenharmony_ci sq_y = new_mpd(); 787db96d56Sopenharmony_ci mpd_set_u32(sq_x, 0, ctx); 797db96d56Sopenharmony_ci mpd_set_u32(sq_y, 0, ctx); 807db96d56Sopenharmony_ci 817db96d56Sopenharmony_ci two = new_mpd(); 827db96d56Sopenharmony_ci four = new_mpd(); 837db96d56Sopenharmony_ci mpd_set_u32(two, 2, ctx); 847db96d56Sopenharmony_ci mpd_set_u32(four, 4, ctx); 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci c = new_mpd(); 877db96d56Sopenharmony_ci mpd_set_u32(c, 0, ctx); 887db96d56Sopenharmony_ci 897db96d56Sopenharmony_ci for (i = 0; i < maxiter && mpd_cmp(c, four, ctx) <= 0; i++) { 907db96d56Sopenharmony_ci mpd_mul(y, x, y, ctx); 917db96d56Sopenharmony_ci mpd_mul(y, y, two, ctx); 927db96d56Sopenharmony_ci mpd_add(y, y, y0, ctx); 937db96d56Sopenharmony_ci 947db96d56Sopenharmony_ci mpd_sub(x, sq_x, sq_y, ctx); 957db96d56Sopenharmony_ci mpd_add(x, x, x0, ctx); 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci mpd_mul(sq_x, x, x, ctx); 987db96d56Sopenharmony_ci mpd_mul(sq_y, y, y, ctx); 997db96d56Sopenharmony_ci mpd_add(c, sq_x, sq_y, ctx); 1007db96d56Sopenharmony_ci } 1017db96d56Sopenharmony_ci 1027db96d56Sopenharmony_ci mpd_del(c); 1037db96d56Sopenharmony_ci mpd_del(four); 1047db96d56Sopenharmony_ci mpd_del(two); 1057db96d56Sopenharmony_ci mpd_del(sq_y); 1067db96d56Sopenharmony_ci mpd_del(sq_x); 1077db96d56Sopenharmony_ci mpd_del(y); 1087db96d56Sopenharmony_ci mpd_del(x); 1097db96d56Sopenharmony_ci 1107db96d56Sopenharmony_ci return i; 1117db96d56Sopenharmony_ci} 1127db96d56Sopenharmony_ci 1137db96d56Sopenharmony_ciint 1147db96d56Sopenharmony_cimain(int argc, char **argv) 1157db96d56Sopenharmony_ci{ 1167db96d56Sopenharmony_ci mpd_context_t ctx; 1177db96d56Sopenharmony_ci mpd_t *x0, *y0; 1187db96d56Sopenharmony_ci mpd_t *sqrt_2, *xstep, *ystep; 1197db96d56Sopenharmony_ci mpd_ssize_t prec = 19; 1207db96d56Sopenharmony_ci 1217db96d56Sopenharmony_ci long iter = 1000; 1227db96d56Sopenharmony_ci int points[40][80]; 1237db96d56Sopenharmony_ci int i, j; 1247db96d56Sopenharmony_ci clock_t start_clock, end_clock; 1257db96d56Sopenharmony_ci 1267db96d56Sopenharmony_ci 1277db96d56Sopenharmony_ci if (argc != 3) { 1287db96d56Sopenharmony_ci fprintf(stderr, "usage: ./bench prec iter\n"); 1297db96d56Sopenharmony_ci exit(1); 1307db96d56Sopenharmony_ci } 1317db96d56Sopenharmony_ci prec = strtoll(argv[1], NULL, 10); 1327db96d56Sopenharmony_ci iter = strtol(argv[2], NULL, 10); 1337db96d56Sopenharmony_ci 1347db96d56Sopenharmony_ci mpd_init(&ctx, prec); 1357db96d56Sopenharmony_ci /* no more MPD_MINALLOC changes after here */ 1367db96d56Sopenharmony_ci 1377db96d56Sopenharmony_ci sqrt_2 = new_mpd(); 1387db96d56Sopenharmony_ci xstep = new_mpd(); 1397db96d56Sopenharmony_ci ystep = new_mpd(); 1407db96d56Sopenharmony_ci x0 = new_mpd(); 1417db96d56Sopenharmony_ci y0 = new_mpd(); 1427db96d56Sopenharmony_ci 1437db96d56Sopenharmony_ci mpd_set_u32(sqrt_2, 2, &ctx); 1447db96d56Sopenharmony_ci mpd_sqrt(sqrt_2, sqrt_2, &ctx); 1457db96d56Sopenharmony_ci mpd_div_u32(xstep, sqrt_2, 40, &ctx); 1467db96d56Sopenharmony_ci mpd_div_u32(ystep, sqrt_2, 20, &ctx); 1477db96d56Sopenharmony_ci 1487db96d56Sopenharmony_ci start_clock = clock(); 1497db96d56Sopenharmony_ci mpd_copy(y0, sqrt_2, &ctx); 1507db96d56Sopenharmony_ci for (i = 0; i < 40; i++) { 1517db96d56Sopenharmony_ci mpd_copy(x0, sqrt_2, &ctx); 1527db96d56Sopenharmony_ci mpd_set_negative(x0); 1537db96d56Sopenharmony_ci for (j = 0; j < 80; j++) { 1547db96d56Sopenharmony_ci points[i][j] = color_point(x0, y0, iter, &ctx); 1557db96d56Sopenharmony_ci mpd_add(x0, x0, xstep, &ctx); 1567db96d56Sopenharmony_ci } 1577db96d56Sopenharmony_ci mpd_sub(y0, y0, ystep, &ctx); 1587db96d56Sopenharmony_ci } 1597db96d56Sopenharmony_ci end_clock = clock(); 1607db96d56Sopenharmony_ci 1617db96d56Sopenharmony_ci#ifdef BENCH_VERBOSE 1627db96d56Sopenharmony_ci for (i = 0; i < 40; i++) { 1637db96d56Sopenharmony_ci for (j = 0; j < 80; j++) { 1647db96d56Sopenharmony_ci if (points[i][j] == iter) { 1657db96d56Sopenharmony_ci putchar('*'); 1667db96d56Sopenharmony_ci } 1677db96d56Sopenharmony_ci else if (points[i][j] >= 10) { 1687db96d56Sopenharmony_ci putchar('+'); 1697db96d56Sopenharmony_ci } 1707db96d56Sopenharmony_ci else if (points[i][j] >= 5) { 1717db96d56Sopenharmony_ci putchar('.'); 1727db96d56Sopenharmony_ci } 1737db96d56Sopenharmony_ci else { 1747db96d56Sopenharmony_ci putchar(' '); 1757db96d56Sopenharmony_ci } 1767db96d56Sopenharmony_ci } 1777db96d56Sopenharmony_ci putchar('\n'); 1787db96d56Sopenharmony_ci } 1797db96d56Sopenharmony_ci putchar('\n'); 1807db96d56Sopenharmony_ci#else 1817db96d56Sopenharmony_ci (void)points; /* suppress gcc warning */ 1827db96d56Sopenharmony_ci#endif 1837db96d56Sopenharmony_ci 1847db96d56Sopenharmony_ci printf("time: %f\n\n", (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC); 1857db96d56Sopenharmony_ci 1867db96d56Sopenharmony_ci mpd_del(y0); 1877db96d56Sopenharmony_ci mpd_del(x0); 1887db96d56Sopenharmony_ci mpd_del(ystep); 1897db96d56Sopenharmony_ci mpd_del(xstep); 1907db96d56Sopenharmony_ci mpd_del(sqrt_2); 1917db96d56Sopenharmony_ci 1927db96d56Sopenharmony_ci return 0; 1937db96d56Sopenharmony_ci} 194