From 4979af381584035ad4cbcc08dfb4819e1253991c Mon Sep 17 00:00:00 2001 From: William Hart Date: Mon, 15 Apr 2013 22:59:58 +0100 Subject: [PATCH] Added mulmid and div/divrem/divapprox profiling code. --- profile/p-nn_div_divconquer.c | 114 ++++++++++++++++++++++++++ profile/p-nn_divapprox_divconquer.c | 12 +-- profile/p-nn_divrem_divconquer.c | 12 +-- profile/p-nn_mulmid_kara.c | 4 +- profile/p-nn_mulmid_vs_mul.c | 122 ++++++++++++++++++++++++++++ 5 files changed, 250 insertions(+), 14 deletions(-) create mode 100644 profile/p-nn_div_divconquer.c create mode 100644 profile/p-nn_mulmid_vs_mul.c diff --git a/profile/p-nn_div_divconquer.c b/profile/p-nn_div_divconquer.c new file mode 100644 index 0000000..5c023d9 --- /dev/null +++ b/profile/p-nn_div_divconquer.c @@ -0,0 +1,114 @@ +/* + Copyright (C) 2013 William Hart + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include +#include "nn.h" +#include "test.h" + +#undef ITER +#define ITER 10000 + +rand_t state; + +void time_div_divconquer(void) +{ + nn_t a, a2, b, q1, q2; + len_t size; + word_t inv; + long count, i; + clock_t t; + + TMP_INIT; + + for (size = 370; size < 1000; size = (long) ceil(size*1.1)) + { + TMP_START; + + a = TMP_ALLOC(2*size - 1); + a2 = TMP_ALLOC(2*size - 1); + b = TMP_ALLOC(size); + q1 = TMP_ALLOC(size); + q2 = TMP_ALLOC(size); + + printf("size = %ld: ", size); + + t = clock(); + for (i = 0; i < 10; i++) + { + randoms_of_len(size, ANY, state, &b, NULL); + b[size - 1] |= (1UL<<(WORD_BITS - 1)); + randoms_of_len(2*size - 1, ANY, state, &a, NULL); + inv = precompute_inverse2(b[size - 1], b[size - 2]); + + for (count = 0; count < ITER/10; count++) + { + nn_copy(a2, a, 2*size - 1); + nn_divrem_classical_preinv_c(q1, a2, 2*size - 1, b, size, inv, 0); + } + } + t = clock() - t; + + printf("classical = %gs, ", ((double) t)/CLOCKS_PER_SEC/ITER); + + t = clock(); + for (i = 0; i < 10; i++) + { + randoms_of_len(size, ANY, state, &b, NULL); + b[size - 1] |= (1UL<<(WORD_BITS - 1)); + randoms_of_len(2*size - 1, ANY, state, &a, NULL); + inv = precompute_inverse2(b[size - 1], b[size - 2]); + + for (count = 0; count < ITER/10; count++) + { + nn_copy(a2, a, 2*size - 1); + nn_div_divconquer_preinv_c(q2, a2, 2*size - 1, b, size, inv, 0); + } + } + t = clock() - t; + + printf("divconquer = %gs\n", ((double) t)/CLOCKS_PER_SEC/ITER); + + TMP_END; + } +} + +int main(void) +{ + printf("\nTiming nn_div_divconquer vs nn_divrem_classical:\n"); + + randinit(&state); + + time_div_divconquer(); + + randclear(state); + + return 0; +} + diff --git a/profile/p-nn_divapprox_divconquer.c b/profile/p-nn_divapprox_divconquer.c index de324ba..080ff27 100644 --- a/profile/p-nn_divapprox_divconquer.c +++ b/profile/p-nn_divapprox_divconquer.c @@ -62,9 +62,9 @@ void time_divapprox_divconquer(void) t = clock(); for (i = 0; i < 10; i++) { - mpn_random(b, size); - b[size - 1] |= GMP_LIMB_HIGHBIT; - mpn_random(a, 2*size - 1); + randoms_of_len(size, ANY, state, &b, NULL); + b[size - 1] |= (1UL<<(WORD_BITS - 1)); + randoms_of_len(2*size - 1, ANY, state, &a, NULL); inv = precompute_inverse2(b[size - 1], b[size - 2]); for (count = 0; count < ITER/10; count++) @@ -80,9 +80,9 @@ void time_divapprox_divconquer(void) t = clock(); for (i = 0; i < 10; i++) { - mpn_random(b, size); - b[size - 1] |= GMP_LIMB_HIGHBIT; - mpn_random(a, 2*size - 1); + randoms_of_len(size, ANY, state, &b, NULL); + b[size - 1] |= (1UL<<(WORD_BITS - 1)); + randoms_of_len(2*size - 1, ANY, state, &a, NULL); inv = precompute_inverse2(b[size - 1], b[size - 2]); for (count = 0; count < ITER/10; count++) diff --git a/profile/p-nn_divrem_divconquer.c b/profile/p-nn_divrem_divconquer.c index dc9fcd5..6c8ff8d 100644 --- a/profile/p-nn_divrem_divconquer.c +++ b/profile/p-nn_divrem_divconquer.c @@ -62,9 +62,9 @@ void time_divrem_divconquer(void) t = clock(); for (i = 0; i < 10; i++) { - mpn_random(b, size); + randoms_of_len(size, ANY, state, &b, NULL); b[size - 1] |= (1UL<<(WORD_BITS - 1)); - mpn_random(a, 2*size - 1); + randoms_of_len(2*size - 1, ANY, state, &a, NULL); inv = precompute_inverse2(b[size - 1], b[size - 2]); for (count = 0; count < ITER/10; count++) @@ -78,9 +78,9 @@ void time_divrem_divconquer(void) t += clock(); for (i = 0; i < 10; i++) { - mpn_random(b, size); + randoms_of_len(size, ANY, state, &b, NULL); b[size - 1] |= (1UL<<(WORD_BITS - 1)); - mpn_random(a, 2*size - 1); + randoms_of_len(2*size - 1, ANY, state, &a, NULL); inv = precompute_inverse2(b[size - 1], b[size - 2]); for (count = 0; count < ITER/10; count++) @@ -97,9 +97,9 @@ void time_divrem_divconquer(void) t = clock(); for (i = 0; i < 10; i++) { - mpn_random(b, size); + randoms_of_len(size, ANY, state, &b, NULL); b[size - 1] |= (1UL<<(WORD_BITS - 1)); - mpn_random(a, 2*size - 1); + randoms_of_len(2*size - 1, ANY, state, &a, NULL); inv = precompute_inverse2(b[size - 1], b[size - 2]); for (count = 0; count < ITER/10; count++) diff --git a/profile/p-nn_mulmid_kara.c b/profile/p-nn_mulmid_kara.c index 8e7eba8..a56de9c 100644 --- a/profile/p-nn_mulmid_kara.c +++ b/profile/p-nn_mulmid_kara.c @@ -62,14 +62,14 @@ void time_mulmid_kara(void) t = clock(); for (count = 0; count < ITER; count++) - mpn_mul(r1, a, 2*size, b, size); + nn_mulmid_classical(r1 + size, r1, a, 2*size, b, size); t = clock() - t; printf("classical = %gs, ", ((double) t)/CLOCKS_PER_SEC/ITER); t = clock(); for (count = 0; count < ITER; count++) - mpn_mulmid(r2, a, 2*size, b, size); + nn_mulmid_kara(r2 + size, r2, a, 2*size, b, size); t = clock() - t; printf("kara = %gs\n", ((double) t)/CLOCKS_PER_SEC/ITER); diff --git a/profile/p-nn_mulmid_vs_mul.c b/profile/p-nn_mulmid_vs_mul.c new file mode 100644 index 0000000..069c10e --- /dev/null +++ b/profile/p-nn_mulmid_vs_mul.c @@ -0,0 +1,122 @@ +/* + Copyright (C) 2013 William Hart + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include +#include "nn.h" +#include "test.h" + +#undef ITER +#define ITER 25000 + +rand_t state; + +void time_mulmid_kara(void) +{ + nn_t a, b, r1, r2; + len_t size; + long count; + clock_t t; + + TMP_INIT; + + for (size = 2; size < 4000; size = (long) ceil(size*1.1)) + { + TMP_START; + + a = TMP_ALLOC(2*size); + b = TMP_ALLOC(size); + r1 = TMP_ALLOC(size + 3); + r2 = TMP_ALLOC(3*size); + + randoms_of_len(2*size, ANY, state, &a, NULL); + randoms_of_len(size, ANY, state, &b, NULL); + + printf("size = %ld: ", size); + + if (size < 100) + { + t = clock(); + for (count = 0; count < ITER; count++) + nn_mulmid_classical(r1 + size + 1, r1, a, 2*size, b, size); + t = clock() - t; + + printf("mulmid_classical = %gs, ", ((double) t)/CLOCKS_PER_SEC/ITER); + } + + t = clock(); + for (count = 0; count < ITER; count++) + nn_mulmid_kara(r1 + size + 1, r2, a, 2*size, b, size); + t = clock() - t; + + printf("mulmid_kara = %gs\n", ((double) t)/CLOCKS_PER_SEC/ITER); + + printf("size = %ld: ", size); + + if (size < 100) + { + t = clock(); + for (count = 0; count < ITER; count++) + nn_mul_classical(r2, a, 2*size, b, size); + t = clock() - t; + + printf("mul_classical = %gs, ", ((double) t)/CLOCKS_PER_SEC/ITER); + } + + t = clock(); + for (count = 0; count < ITER; count++) + nn_mul(r2, a, 2*size, b, size); + t = clock() - t; + + printf("mul = %gs, ", ((double) t)/CLOCKS_PER_SEC/ITER); + + t = clock(); + for (count = 0; count < ITER; count++) + nn_mullow(r2 + 2*size, r2, a, 2*size, b, size); + t = clock() - t; + + printf("mullow = %gs\n", ((double) t)/CLOCKS_PER_SEC/ITER); + + TMP_END; + } +} + +int main(void) +{ + printf("\nTiming nn_mulmid_kara vs nn_mulmid_classical:\n"); + + randinit(&state); + + time_mulmid_kara(); + + randclear(state); + + return 0; +} +