diff --git a/benchmarks/core/mod_inv.bril b/benchmarks/core/mod_inv.bril new file mode 100644 index 000000000..14463fa2b --- /dev/null +++ b/benchmarks/core/mod_inv.bril @@ -0,0 +1,85 @@ +# ARGS: 46, 10007 +@main(n: int, p: int) { + v0: int = const 2; + two: int = id v0; + v1: int = id p; + v2: int = id two; + v3: int = sub v1 v2; + m: int = id v3; + v4: int = const 1; + ans: int = id v4; + v5: int = id n; + a: int = id v5; + v7: int = const 1; + i: int = id v7; +.for.cond.6: + v8: int = id m; + v9: int = const 0; + v10: bool = gt v8 v9; + br v10 .for.body.6 .for.end.6; +.for.body.6: + v12: int = id m; + v13: int = id m; + v14: int = id two; + v15: int = div v13 v14; + v16: int = id two; + v17: int = mul v15 v16; + v18: bool = eq v12 v17; + br v18 .then.11 .else.11; +.then.11: + jmp .endif.11; +.else.11: + v19: int = id ans; + v20: int = id a; + v21: int = mul v19 v20; + v22: int = id p; + v23: int = call @mod v21 v22; + ans: int = id v23; +.endif.11: + v24: int = id a; + v25: int = id a; + v26: int = mul v24 v25; + v27: int = id p; + v28: int = call @mod v26 v27; + a: int = id v28; + v29: int = id m; + v30: int = id two; + v31: int = div v29 v30; + m: int = id v31; + jmp .for.cond.6; +.for.end.6: + v32: int = id ans; + print v32; + v33: int = const 0; +} +@mod(n: int, p: int): int { + v0: int = id n; + v1: int = id n; + v2: int = id p; + v3: int = div v1 v2; + v4: int = id p; + v5: int = mul v3 v4; + v6: int = sub v0 v5; + ret v6; +} + +# function main(n: bigint, p: bigint) { +# var two: bigint = 2; +# var m: bigint = p - two; +# var ans: bigint = 1; +# var a: bigint = n; +# for (let i = 1; m > 0; m = m / two) { +# if (m == m / two * two) { +# } +# else { +# ans = mod(ans * a, p); +# } +# a = mod(a * a, p); +# } +# console.log(ans); +# } +# +# function mod(n: bigint, p: bigint): bigint { +# return n - n / p * p; +# } + diff --git a/benchmarks/core/mod_inv.out b/benchmarks/core/mod_inv.out new file mode 100644 index 000000000..6726ecf8d --- /dev/null +++ b/benchmarks/core/mod_inv.out @@ -0,0 +1 @@ +2393 diff --git a/benchmarks/core/mod_inv.prof b/benchmarks/core/mod_inv.prof new file mode 100644 index 000000000..d62b26752 --- /dev/null +++ b/benchmarks/core/mod_inv.prof @@ -0,0 +1 @@ +total_dyn_inst: 558 diff --git a/docs/tools/bench.md b/docs/tools/bench.md index 162264752..1f8543c8b 100644 --- a/docs/tools/bench.md +++ b/docs/tools/bench.md @@ -35,6 +35,7 @@ The current benchmarks are: * `mat-inv` : Calculates the inverse of a 3x3 matrix and prints it out. * `mat-mul`: Multiplies two `nxn` matrices using the [naive][matmul] matrix multiplication algorithm. The matrices are randomly generated using a [linear congruential generator][rng]. * `max-subarray`: solution to the classic Maximum Subarray problem. +* `mod_inv`: Calculates the [modular inverse][modinv] of `n` under to a prime modulus p. * `newton`: Calculate the square root of 99,999 using the [newton method][newton] * `n_root`: Calculate nth root of a float using newton's method. * `orders`: Compute the order ord(u) for each u in a cyclic group [][cgroup] of integers modulo *n* under the group operation + (modulo *n*). Set the second argument *is_lcm* to true if you would like to compute the orders using the lowest common multiple and otherwise the program will use the greatest common divisor. @@ -83,3 +84,4 @@ Credit for several of these benchmarks goes to Alexa VanHattum and Gregory Yaune [mandelbrot]: https://en.wikipedia.org/wiki/Mandelbrot_set [hanoi]: https://en.wikipedia.org/wiki/Tower_of_Hanoi [euler]: https://en.wikipedia.org/wiki/E_(mathematical_constant) +[modinv]: https://en.wikipedia.org/wiki/Modular_multiplicative_inverse